Latest Results
fix(scanner): find a SOPS value's span in linear time
The span of a SOPS value came from a regex that takes an optional assignment before the
ENC[AES256_GCM, envelope. On a long run of name characters the regex retried that run at every
position of the line: a 40,000-character line, such as a minified bundle's, took guard 49 seconds,
against 0.7 on main, and 200,000 characters ran past the scanner's time limit.
The envelope is now found with str.find, and its assignment by stepping back from it, so a line
costs time linear in its length. The spans are exactly the regex's matches: a test compares them
on 20,000 random lines.
Reported by CodeRabbit on #936.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015t5xQ3d6X4RCFUakwDh9CEclaude/quirky-fermi-5rga33 fix(scanner): skip only an encrypted value, not the plaintext after it on its line
With lines counted as git counts them (#937), a form feed no longer starts a line, so a
plaintext key after an encrypted value shares the value's line. The native scanner skipped
that whole line, and the engine dropped every finding on it, so no scanner reported the key
(reported by CodeRabbit on #936). The engine already dropped gitleaks' finding of a key after
a space there.
Only the value is skipped now: a dotenvx value to the end of its encrypted: token, a SOPS
value to the end of its ENC[AES256_GCM,...] envelope, and dotenvx's public key. The native
pattern and entropy scans leave out the matches that overlap one. The engine drops an
external finding whose column is in one and, as before, one without a column on its line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015t5xQ3d6X4RCFUakwDh9CEclaude/quirky-fermi-5rga33 fix(scanner): count lines as git does, not at form feeds or Unicode line separators
The scanner split files into lines with str.splitlines(), which also breaks a line at a
vertical tab, a form feed, \x1c to \x1e, \x85, U+2028 and U+2029. git, grep and the external
scanners do not (#937). So after one of them:
- the native scanner put a finding a line lower than gitleaks and grep did;
- an "# envdrift:ignore" comment on a finding's line did not suppress another scanner's
finding, so guard failed on it;
- in an encrypted .env file, the check for a ciphertext line dropped another scanner's finding
of a plaintext secret, without a word;
- envdrift could not read back the value trivy redacts, and hashed the location instead;
- a sha512crypt hash with a vertical tab or a form feed in its salt, which OpenSSL writes, was
cut in two and not found (reported by CodeRabbit on #936).
split_lines() in envdrift.utils.text splits at \n, \r\n and \r only, as the .env parser does
(#486). The native scanner, the encrypted-line check, the inline ignore check and trivy's value
recovery now all use it. A bare \r stays a line break, as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015t5xQ3d6X4RCFUakwDh9CEclaude/quirky-fermi-5rga33 Latest Branches
0%
claude/quirky-fermi-5rga33 0%
release-please--branches--main--components--envdrift 0%
release-please--branches--main--components--agent © 2026 CodSpeed Technology