Releases: atomdrift-project/filefacts
Releases · atomdrift-project/filefacts
Release list
v1.3.0
Detection & parsing
- PE .NET/CLR metadata (pe.clr.*): managed-binary detection independent of Authenticode — strong-name signing, module MVID, runtime/metadata versions, IL-only bits, and metadata stream inventory.
- Static libraries (.a) now identified as a distinct file type, disambiguated from .deb (both use the ! magic).
- CRX signed-but-unverified detection fixed: the canonical extension ID is now read from the CRX3 signed header, correctly handling Web Store packages that carry a publisher proof before the developer proof (previously derived the wrong ID).
- Dependency extraction for .gem (runtime deps → pkg:gem PURLs) and VSIX ( → pkg:vscode PURLs).
Reliability
- Fixed panic parsing batch (.bat) comments when a line begins with a multibyte char (e.g. CJK) — a rem check byte-sliced mid-character. (Crashed the matrixone scan.)
- Auto-clearing cache: 30-day TTL + 2 GiB ceiling, non-blocking; also sweeps stng's on-disk string cache, which nothing else prunes in a filefacts/cleave process. Fixed an eviction-target overflow on very large max_items.
Project
- Moved to GitHub (atomdrift-project/filefacts); stng dependency re-pinned. Dependency updates.
v1.2.0
Features
- New formats: WebAssembly, OCI container images, Python sdist, Android DEX; better npm/gem/oci/xbps/gpkg detection.
- Recognizes SVG, Cypher/CQL, and Python template files.
- Windowed entropy metrics surface a concealed high-entropy region (peak + offset) even when overall entropy is low.
- Facts now carry byte-range spans pinpointing each measurement's evidence.
- Registry metadata gains a security_hold flag and version_removed metric.
Performance
- Skips the XOR seed search on source/script files with no sign of XOR logic.
- Deduplicates stng strings; cache self-cleans (prunes to 90% of capacity instead of a 30-day TTL).
v1.1.1
- Hermetic open for cache-less testing
- Add missing DMG support file
v1.1.0
- Added external reference extraction: PURLs, URLs, evidence, offsets, hashes.
- Added package/lockfile parsing for npm, PyPI, Cargo, Go, Ruby, Composer, Arch.
- Added new file types: lockfiles, go.mod, go.sum, .SRCINFO, DMG.
- Added package metadata and reference output views.
- Added source call-target metrics, including obfuscated command targets.
- Improved JS/PHP/protobuf/package/DMG identification.
- Improved Go buildinfo, Mach-O slicing, and rizin symbol offsets.
- Added pre-commit hook support.
v1.0.1
- Program Identity extraction — pulls publisher/package metadata from CRX, npm, nupkg, Rust
crate, wheel, and xpi archives - JCL (z/OS Job Control Language) detection; PKGBUILD classified as shell
- Panic-safe binary parsing — goblin wrapped to fail soft on malformed PE/Mach-O/ELF instead of
aborting - Binary fixes — corrected Mach-O FAT and PE offsets; richer PE version/debug info
- Scanning rework — consolidated string scanning, improved wide-char handling
- Dependency updates and cleanup
v1.0.0
New Signals
- Added richer package ecosystem identification: Android/Alpine APK, npm, Cargo crate, Ruby gem, Debian package, NuGet, VSIX, IPA, conda, egg, Arch/FreeBSD/macOS pkg.
- Added .deb identity features: package, version, architecture, maintainer, dependencies, installed size.
- Added .gem identity features: name, version, platform, homepage, authors, licenses, runtime/development dependency counts.
- Added more PE malware-relevant metrics, such as CLR managed resource count, max entropy, max size.
Better Evidence Anchoring
- ELF dynamic imports now include offsets into .dynstr.
- Mach-O dylib references and code signatures now include offsets.
- Source member symbols now include byte offsets.
Detection Quality
- Improved package disambiguation, especially Android vs Alpine .apk, npm .tgz, Arch/FreeBSD/macOS .pkg.
- Better AppleScript and pacman/AUR install-scriptlet detection.
- Reduced false positives by classifying unsupported OCaml, Vim, Lisp, SQL, Smali, patches/diffs, CSS-like files, and TS baselines as text
instead of weakly guessing JS/Kotlin/Batch.
Robustness For Large Corpora
- Hardened Tree-sitter extraction against panics, deep ASTs, huge query output, and scanner-risk cases.
- Added metrics such as ast.depth_capped, source.query_limited.*, and source.ast_unavailable so skipped/truncated AST extraction is explicit.
- Binary string extraction reuses existing PE/ELF/Mach-O parses, reducing duplicate parsing work.
Breaking/Schema Notes
- FileType::Pkg became specific variants like PkgMacos, PkgFreebsd, and PkgArch.
- Symbol::Member now has optional offset.
- New source error stages: SourceParse, SourceExtract, SourceAstWalk.
- pe.cert_table_size moved from values to metrics.
v0.9.5
Features
- Added Debian package metadata: package, version, architecture, maintainer, dependencies, and installed size.
- Added RubyGems metadata: name, version, platform, authors, licenses, homepage, and runtime deps.
- Split package ecosystems into distinct types, including Android/Alpine APK, npm, crate, conda, NuGet, IPA,
VSIX, FreeBSD pkg, and Arch pkg. - Added PE/.NET signals for managed resource entropy/size, suspicious VERSIONINFO identity text, .reloc
overhang, and certificate table size. - Improved AppleScript detection for plaintext macOS stealer scripts with random or unknown extensions.
Performance
- Reuses parsed PE/ELF/Mach-O objects for string extraction instead of parsing binaries twice.
- Skips duplicate stng symbol/import extraction because filefacts already walks symbols itself.
Bugfixes
- Hardened AST analysis against deeply nested source chains that could overflow the worker stack.
- Emits ast.depth_capped when hostile or generated source exceeds analysis depth.
- Reduced false positives by treating Vim, Lisp, SQL, Smali, diffs, and TS baseline files as text.
- Fixed archive disambiguation so legitimate .apk and .pkg ecosystem variants do not look like extension
mismatches.
v0.9.0
New language & format support
- Clojure and Windows Batch AST analysis (tree-sitter)
- AppleScript source detection
- BEAM bytecode and FreeBSD zstd .pkg detection
- binding.gyp parsed as JSON; Meson, Arch package metadata, and R Markdown/Quarto recognized
New facts & metrics
- Comments exposed as a matchable string tier; JS/TS/Go backtick strings no longer misread as comments; Lisp and
Batch comment styles added - New obfuscation AST metrics: operator density, numeric arrays, XOR loops, const/string-return functions, identity
functions, and more - Extension/content mismatch metrics name the transition (e.g. binary_as_image), with carve-outs for benign
conventions - VBA identifier metrics: mean length, entropy, distinct trigger count
- binary.overall_entropy emitted for every file type
- Java constructors, C# qualified names, and import aliases (import x as y) surfaced
Detection accuracy
- Stylesheets treated as text, no longer misparsed as JavaScript
- JS/Kotlin scoring fixed: var/let/const count for JS; === ignored in separator runs
- Python relative imports keep their . prefix — no more false PyPI matches
- PEs that goblin can't parse now get rizin section/import recovery
Performance & memory
- jemalloc tuned to release freed pages immediately: peak RSS −~60%
- JSON output streams to stdout instead of building in memory
- Tree-sitter queries compiled once and cached
API & maintenance
- Symbol objects slimmed: dropped source, decl, and rare rizin fields
- Dependency updates
v0.8.0
Features
- Electron ASAR and Clojure support — new .asar archive parser and Clojure source
identification. - Generic JSON support — .json files are parsed into top-level keys (with a 75 KB cap;
larger files stay analyzable as raw text). - Broader file identification — more extensions in the fileid map, a dedicated PE
extension map, and improved GitHub Actions workflow detection.
Fixes
- Fixed a PDF /Length stream-end calculation bug that mis-bounded stream bodies when
endstream had no preceding EOL.
Hardening
- Capped AST recursion depth at 1000 to stop pathologically nested
(generated/adversarial) source from overflowing the worker stack; ast.max_depth now
saturates at the cap as a "deeply nested" signal.
Internal
- Dependency updates and code cleanup.
v0.7.0
New facts
- Markdown extractor — markdown.first_heading and deduped markdown.github_repos[]
- file.basename / file.stem emitted whenever a path is supplied
- Wheel outer-filename parsing: whl.filename.{name_prefix,version,build,python_tag,abi_tag,platform_tag} from the PEP 427 basename
- PDB derived names — pe.debug.pdb.basename and pe.debug.pdb.stem
Hardening
- Tree-sitter scanner audit. Per-grammar ScannerAudit table re-verified against locked crate sources;
- Python now models the actual combined delimiter + indent byte
- Mach-O fat-binary panic fix — misclassified CAFEBABE Java .class no longer slices OOB on bogus arch.offset.
- Mach-O code-signature caps — Requirement-expression depth 32, plist depth 64, entitlement XML 1 MiB.
- CHM bounds arithmetic — directory / namelist / system walks converted to checked_add / checked_mul.
- bytes_at::{u16,u32,u64}_{le,be} helpers replace unchecked try_into().unwrap() reads.
- CLI — --help / --version no longer process::exit; readdir errors surface per-entry
Breaking API
- unsafe_code = "deny" (was warn).
- FileId fields private — use file_type(), source(), extension_mismatch(). #[non_exhaustive].
- ParseError.kind/.stage are now ErrorKind / Stage enums (JSON wire form unchanged).
- ArchiveMember regrouped into ArchiveCompression / ArchiveOwnership / ArchiveOffsets sub-structs.
- VBA sentinel flattened to filefacts::VBA_NON_LITERAL_SENTINEL; rizin module no longer a re-export façade.
- ParsedFile is #[must_use]; ParsedFile::strings() renamed to text().
- Sections::from_iter_sections removed in favour of standard FromIterator.