Skip to content

Build1 publisher3 min readPublished

Replaying 8,900 real files cut a file-type detector's false alarms from 105 to zero

A file-type detector passed 260 tests and scored 100% on a hand-built benchmark. Pointed at about 8,900 files already sitting on the author's PC, it called thirteen System32 files dangerous and hung for minutes on one .ini.

The Engineer · Build desk

Illustration accompanying Replaying 8,900 real files cut a file-type detector's false alarms from 105 to zero

What happened

  • The developer's file-type identifier had 260 passing tests and a hand-made benchmark that scored 100% before it met any file it had not been written to expect.
  • Pointed at the files already on the author's own PC, it flagged thirteen files in C:\Windows\System32 as dangerous, called ninety Tcl message files a mismatch, and stalled for several minutes on one .ini.
  • Accuracy on extensions the app knows rose from 69.9% to 90.1% after the fixes, and false alarms on real files went from 105 to none.
  • The causes were dictionary assumptions such as .rs always meaning Rust, plus regex feature rules that backtracked, one of them hanging the detector on Appraiser_Data.ini.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint The 90.1% describes one Windows machine with per-extension caps applied, so a team scanning user documents or a container image cannot inherit the figure without rerunning the sweep on their own disk.
  • capability Any code that sniffs formats can grade itself without a labelled dataset, because stripping the extension and asking for it back turns the host's own disk into a test set.
  • exposure A feature set made of regexes is a denial-of-service surface for whoever runs it, since ordinary machine-written config files on the same disk can stall a scan for minutes.
  • decision Anyone adding this replay to CI has to decide what a red build means when the answer key is unreliable, because a lying extension is one of the bugs the run finds.

The harness is one loop: for each file it records the detector's verdict on the file as it sits, then copies the file to a temp folder with the extension removed and asks the core inspector which extension it would guess [7]. The original extension is the answer key, and the copy arm only runs on files of 12 MB or smaller [22]. For an app written to catch invoice.pdf.exe, the extension is an odd thing to grade against [24]. It is also the only label available without hand-labelling.

That tension is visible in the fixes. Every false-alarm cause the post lists is a case where the extension was not telling the truth about the bytes: .rs that is not Rust, .msg that is not Outlook, .CSS that is HTML, .so holding a Windows DLL [14]. The change went into the dictionary [14]. The headline accuracy number is agreement with extension convention, allowing the aliases the harness defines, and the post calls that a stricter test than identifying the format [11].

A Windows box has roughly 9,000 .js files and 8,000 .dll files, so an uncapped walk measures JavaScript [21]. Sampling decides what the number means. The harness caps each extension per root, 30 per extension under System32 to depth 3, and caps every extension at 90 across all 35 roots [20][19]. Against roughly 8,000 .dll files, 90 is a bit over one percent of them [4]. The sweep is 8,900 files over about 600 extensions, an average near fifteen each [8][5].

Read the gains as error rates: on extensions the app knows, 69.9% to 90.1% means error fell from 30.1% to 9.9%, so about two thirds of the errors are gone [9][1]. On the roughly 130 extensions the post says ordinary users meet, 76.5% to 93.0% is 23.5% error down to 7.0% [10][2]. Unidentified files fell from 5,408 to 3,533, which against the 8,900-file sweep is about 61% down to about 40% [12][3].

One Makefile feature, `(\w[\w.\-/]*\s*)*$`, backtracked exponentially across lines and stalled the detector on a file called Appraiser_Data.ini [15]. That hang is the part I would copy first. Timing every file then turned up four more rules that go quadratic on a single whitespace-free line, all of them starting with `\w+` [16]. The post flags two shapes to grep for, nested quantifiers with a `\s` that eats newlines, and an unanchored `\w+` at the start [17].

The cheapest fix was the confidence rule. The author wrote that "high confidence" requires two different features to match, and that "Repeating one feature, however many times, never counts as certainty" [18].

For the 90.1% to say anything about your build, your inputs would have to be written by the same population of tools: Office, Git, the Windows Kits, a Python install, one developer's dev folder [20]. The loop ports to any format-sniffing code with a directory to walk. The app is closed source and ships on the Microsoft Store, so the run cannot be reproduced from a repository [23].

What to watch

  • Whether the results table shows format accuracy diverging from the extension-match figure the summary leads with.
  • Whether a per-file time budget ships as a guard, or timing stays a diagnostic the author runs by hand.
  • Whether the same loop, run against a Linux image or a share of user documents, moves the 90.1%.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories