You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
application/utils/harvester/diff_parser.py's DiffParser.parse() extracts changed files from a git diff using a regex on the diff --git a/<path> b/<path> header line: match = re.match(r"diff --git a/(.+?) b/", line) then current_file = match.group(1) if match else None.
This regex makes two incorrect assumptions about real-world git diff output, causing two distinct failure modes: silent data loss for non-ASCII filenames, and silent path corruption for filenames containing " b/".
Reproduction
I wrote a small, self-contained script that creates a real temporary git repository, commits real files, generates a real git diff from it, and runs that through the actual DiffParser class — no mocked/synthetic diff text, just real git output.
Bug reproduction video:
Bug.mp4
Expected behavior
Bug A: should return 1 DiffBlock with file_path='café.md' and added_lines=['added line']
Bug B: should return 1 DiffBlock with file_path='foo b/bar.md'
Actual behavior
Bug A: returns 0 blocks — the entire change is silently discarded, no error or warning
Bug B: returns 1 block, but with file_path truncated to 'foo', silently mis-attributing the change to a nonexistent path
Root cause
The regex in diff_parser.py:39 assumes the header always starts with a literal a/ and that the first " b/" substring found is the real separator. Neither assumption holds:
Git C-quotes (wraps in "...", escapes non-ASCII bytes) any path with non-ASCII characters by default (core.quotePath=true is git's default), so the header doesn't start with a literal a/ at all in that case — the regex simply fails to match.
The non-greedy match stops at the first" b/" substring in the line, which is ambiguous whenever the real file path itself contains that exact substring.
Existing tests in application/tests/harvester_test/diff_parser_test.py only cover plain ASCII, single-word filenames with no path-quoting or embedded " b/" — this class of edge case is completely untested.
Impact
The harvester watches external standard repositories for changes so OpenCRE can stay in sync. A real update to a file with a non-ASCII name (plausible for translated/localized docs in an international project) would be silently missed entirely — no error, no log, just as if the change never happened. A file whose path contains " b/" would have its change detected but filed under the wrong document identity, corrupting downstream traceability.
Suggested fix direction
Parse the file path from the --- a/<path> / +++ b/<path> lines instead of the diff --git header line — git provides these separately per side, avoiding the ambiguity of a single combined header line. Would also need proper un-quoting of git's C-quoted path format. Happy to open a PR for this.
Description
application/utils/harvester/diff_parser.py'sDiffParser.parse()extracts changed files from agit diffusing a regex on thediff --git a/<path> b/<path>header line:match = re.match(r"diff --git a/(.+?) b/", line)thencurrent_file = match.group(1) if match else None.This regex makes two incorrect assumptions about real-world git diff output, causing two distinct failure modes: silent data loss for non-ASCII filenames, and silent path corruption for filenames containing
" b/".Reproduction
I wrote a small, self-contained script that creates a real temporary git repository, commits real files, generates a real
git difffrom it, and runs that through the actualDiffParserclass — no mocked/synthetic diff text, just real git output.Bug reproduction video:
Bug.mp4
Expected behavior
DiffBlockwithfile_path='café.md'andadded_lines=['added line']DiffBlockwithfile_path='foo b/bar.md'Actual behavior
file_pathtruncated to'foo', silently mis-attributing the change to a nonexistent pathRoot cause
The regex in
diff_parser.py:39assumes the header always starts with a literala/and that the first" b/"substring found is the real separator. Neither assumption holds:"...", escapes non-ASCII bytes) any path with non-ASCII characters by default (core.quotePath=trueis git's default), so the header doesn't start with a literala/at all in that case — the regex simply fails to match." b/"substring in the line, which is ambiguous whenever the real file path itself contains that exact substring.Existing tests in
application/tests/harvester_test/diff_parser_test.pyonly cover plain ASCII, single-word filenames with no path-quoting or embedded" b/"— this class of edge case is completely untested.Impact
The harvester watches external standard repositories for changes so OpenCRE can stay in sync. A real update to a file with a non-ASCII name (plausible for translated/localized docs in an international project) would be silently missed entirely — no error, no log, just as if the change never happened. A file whose path contains
" b/"would have its change detected but filed under the wrong document identity, corrupting downstream traceability.Suggested fix direction
Parse the file path from the
--- a/<path>/+++ b/<path>lines instead of thediff --githeader line — git provides these separately per side, avoiding the ambiguity of a single combined header line. Would also need proper un-quoting of git's C-quoted path format. Happy to open a PR for this.