Skip to content

v1.2.2

Choose a tag to compare

@saberzero1 saberzero1 released this 22 Sep 20:32
· 4 commits to main since this release
v1.2.2
136ebd8

Hardening follow-up to v1.2.1. That release fixed one regular expression that could stall a job; this one audits every regular expression in the action and adds a lint rule so the class of bug cannot return.

Fixed

Manifest author check could stall on a large author field

The email detector anchored its local part with a leading \b. Because the character class contains non-word characters (., %, +, -), a word boundary exists part-way through a crafted author value, so the match restarted at each one and rescanned the remainder — quadratic. A 256 KB author field cost about 33 seconds.

A lookbehind now pins matching to run boundaries. The check also became slightly stricter as a side effect: local parts beginning with punctuation, such as .name@example.com, are now detected where the old \b skipped them. Verified across two million randomised inputs, the new form never misses an address the old one caught.

README checks could stall on crafted markdown

The markdown image, <img> and generic HTML tag patterns each permitted their own opening delimiter inside the character class. A run of ![![![ or <img<img therefore restarted the match at every offset and rescanned the rest of the README each time. Excluding the delimiter bounds each attempt.

Stylelint output parsing could backtrack

\s matches newlines, which made the surrounding ^ and $ anchors ambiguous under the m flag. Only horizontal whitespace can pad the JSON line, so the class is now explicit.

Unknown-field lookup rewritten

/unknown field: (.*)\.$/ was quadratic, and every regular-expression form of it remains so because the literal prefix itself re-matches. It is now a plain indexOf and slice, which is linear and additionally preserves field names containing a period.

Added

Lint gate for ReDoS

eslint-plugin-redos now runs as part of npm run lint, which CI already executes. It performs the same automata-based analysis as recheck, reporting the worst-case complexity class of each pattern. A regular expression that backtracks superlinearly now fails the build, instead of surfacing later as a job that hangs on a large enough input.

All 41 regular expressions in src/ are reported safe under this rule.

Full Changelog: v1.2.1...v1.2.2