Skip to content

Skip unusable .gitignore lines instead of aborting the scan - #51

Merged
sabbaticas merged 2 commits into
mainfrom
fix/malformed-gitignore-aborts-scan
Oct 11, 2026
Merged

sabbaticas merged 2 commits into
mainfrom
fix/malformed-gitignore-aborts-scan

Conversation

@sabbaticas

Copy link
Copy Markdown
Contributor

Closes #50.

Summary

  • A .gitignore line panopticas cannot process is now skipped, and the rest of the file still applies. Previously it aborted the whole scan with a traceback.
  • A .gitignore that is not valid UTF-8 no longer aborts the scan either.
  • Separately, the changelog entry for the Click floor now cites the advisory behind it. That is its own commit.

The bug

.gitignore content Before Git
a[b-a]c — a character range written backwards re.error: bad character range Skips the line
\ — a lone backslash GitIgnorePatternError: Invalid git pattern Skips the line
Bytes that are not valid UTF-8 UnicodeDecodeError Reads the file as bytes

load_gitignore_patterns() opened the file as strict UTF-8 and handed every line to pathspec in one call, catching nothing. assess, urls, ai and every caller of identify_files() failed on a repository Git handles without complaint. Not a regression: the matcher replaced in #25 failed the same way.

The fix

  • _ignore_spec() compiles patterns one line at a time and skips a line that raises ValueError (pathspec's GitIgnorePatternError is a subclass) or re.error. Order is preserved, because a later negation overrides an earlier match.
  • load_gitignore_patterns() opens the file with errors='replace'.

Skipping is silent, as it is in Git.

Testing

  • pytest -W error::DeprecationWarning: 780 passed, on pathspec 1.1.1 and on 1.0.0.
  • TestMalformedGitignore covers all three cases, a negation line after the bad one, and that the built-in exclusions survive. All six tests failed before the change.
  • Across 167 cloned repositories, find_files() selects exactly the same files before and after, confirming that compiling line by line changes nothing for a well-formed .gitignore.
  • The reproduction in A malformed .gitignore line aborts the whole scan #50 now lists the repository's files.

Not changed

A .gitignore that cannot be opened at all, such as a directory with that name, still raises.

The Click changelog entry

The existing entry said only that the floor avoids "a vulnerable Click release". It now sits under a ### Security heading and names CVE-2026-7246 (GHSA-47fr-3ffg-hgmw): command injection through the filename argument of click.edit(), which launches the editor through a shell (CWE-78). panopticas does not call click.edit(), and neither do its other dependencies, so it was not itself exploitable; the floor matters because >=8.3.1 admitted the affected 8.3.1. No code or dependency change in that commit.

🤖 Generated with Claude Code

sabbaticas and others added 2 commits October 11, 2026 12:37
The entry said only that the floor avoids a vulnerable Click release. It
now names CVE-2026-7246 (GHSA-47fr-3ffg-hgmw): command injection through
the filename argument of click.edit(), which launches the editor through
a shell (CWE-78), and moves under a Security heading.

panopticas does not call click.edit() and neither do its other
dependencies, so it was not itself exploitable. The floor matters because
>=8.3.1 admitted the affected 8.3.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A line pathspec cannot compile, such as a character range written
backwards or a lone backslash, raised out of load_gitignore_patterns()
and took the whole scan with it. A .gitignore that was not valid UTF-8
raised UnicodeDecodeError the same way. Git accepts all three, skips
what it cannot use and applies the rest.

Patterns are now compiled one line at a time and a line that fails is
skipped, with order preserved so a later negation still overrides an
earlier match. The file is read with errors='replace'.

A .gitignore with no such lines produces the same matcher as before.

Closes #50

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sabbaticas
sabbaticas merged commit f3cbffb into main Oct 11, 2026
4 checks passed
@sabbaticas
sabbaticas deleted the fix/malformed-gitignore-aborts-scan branch October 11, 2026 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A malformed .gitignore line aborts the whole scan

1 participant