Skip to content

v0.9.10 — One finding per block, a quieter default

Choose a tag to compare

@nrodear nrodear released this 02 Aug 21:27
· 269 commits to main since this release

A small release, tagged the same day as 0.9.9. No rule gained or lost a
single finding
— the 13,355-file reference corpus stays at exactly
560,964 across all 141 rules that fire, verified rule by rule rather
than on the total. What changed is how findings are reported.

That is also why this is a new version instead of a re-publish of 0.9.9: the
SCA021 message is part of the SARIF fingerprint, and shipping the new text
under the old number would have meant two tools that hash differently while
claiming to be the same one.

Full notes: docs/releases/v0.9.10.md
· deutsch

Breaking for baselines

  • SCA021 names the real line range: Code block (lines 513-533, 8 matched lines) appears 2x in file. The old number counted normalised
    lines while the marked region counts source lines, so message and
    highlight could never agree — a block reported as "8 lines" could easily
    span twenty-one, because blank lines and comments do not count towards
    the match but do occupy the range. The fingerprint hashes the message, so
    all 9,148 SCA021 findings on the corpus appear once as new against an
    existing baseline. Re-run with --write-baseline after upgrading. No
    other rule's text changed and the finding count is identical.

Highlights

  • The default profile no longer leads with taste. Six rules made
    45.4 % of all findings on the reference corpus — all correct, all with
    a false-positive rate between 0 and 4 %, all matters of house style rather
    than defects: PublicMemberWithoutDoc (15.9 %), NilComparison (9.1 %),
    BeginEndRequired (6.2 %), WithStatement (5.3 %), ClassPerFile
    (4.6 %), DfmHardcodedCaption (4.3 %). They now live in a new style
    profile. default is everything else and is built as all rules minus
    style
    , so a newly added rule cannot fall through the gap; strict
    still means everything.

  • The IDE draws the range bracket in the gutter — and it is visible now.
    The first attempt was not: the cap is drawn from its rectangle's left edge
    rightwards, which is right in the code area where the stripe is
    left-aligned, but the gutter bar is right-aligned and two pixels wide. The
    cap therefore covered exactly the two pixels already filled in the same
    colour and put its remaining seven outside the assigned rectangle. The
    gutter showed a bare bar and never a bracket.

  • A suppression marker inside a finding's range now counts, both as a
    match and as consumed. 0.9.9 merged the per-window SCA021 cascades into
    one finding per block, which meant anyone who had silenced such a cascade
    with eighteen line-bound markers was going to get seventeen SCA165 UnusedSuppression complaints about work already done. That migration step
    is gone.

  • --parallel says when it declined. Per-file parallel scanning falls
    back to serial whenever the run cannot be made deterministic —
    auto-discovery, custom rules, --time-detectors. The fallback used to be
    silent, and it cost us a measurement: a corpus run was started with
    --parallel, AutoDiscoverClasses=1 was set in analyser.ini, the scan
    went serial, and nothing said a word. --parallel is also documented in
    the READMEs for the first time, with the honest figure — ~3 %, because
    the expensive phase (parsing every file, building the symbol and type
    indexes) runs serially before the parallel main loop.

  • Suppression skips files without a single marker, roughly −5 % wall
    clock on the reference corpus. Read that as a direction rather than a
    figure: the two runs with the fast path differ by 5.6 s between
    themselves, and that corpus contains no suppression markers at all, so
    every file takes the fast path — best case, not typical.

  • The standalone search box is debounced, and an empty result no
    longer looks like a clean scan
    : files matching a test-fixture pattern
    (*Demo.pas, *Test*.pas, …) are filtered by default, so analysing a
    file that happens to be named Demo.pas reported "0 findings" with no
    hint why. The filter now names what it dropped and how to keep it.

Corrections to the 0.9.9 notes

Both were found while re-running the gates, and both are corrected in the
CHANGELOG.

  • Error tier "2,172" → 2,134 findings. The figure came from matching
    "level" across the whole SARIF, but tool.driver.rules carries one
    level per rule definition, and the catalogue holds exactly 37 rules
    whose default severity is Error: 2,135 results + 37 definitions = 2,172.
    The v0.9.8 comparison value of 2,255 was measured the same inflated way;
    its corpus baseline no longer exists, so it has been dropped rather than
    silently re-anchored. Total finding counts were never affected — those are
    counted per result, not per level.
  • Rule roster "183 → 195" → 166 → 195. At the v0.9.8 tag the rule
    enumeration holds 166 members; the growth is +29, not +12. The DFM figure
    alongside it (22 → 23) was correct.

Also fixed

  • The Windows version resource of both executables reported 0.9.4.0 in
    its numeric fields while the version string said 0.9.9.0 — the numeric
    part had not been maintained since 0.9.4. Both now agree.

Downloads

  • StaticCodeAnalyser-v0.9.10-Win64.zip — standalone analyser, 64-bit
  • StaticCodeAnalyser-v0.9.10-Win32.zip — standalone analyser, 32-bit
  • StaticCodeAnalyser-v0.9.10-source.zip — full source