Download src/data/diff_utils.py from Dhruv1000/tracegrpo: direct link, hf CLI and curl.
- Browser
- Download file 1.67 kB
-
https://huggingface.co/Dhruv1000/tracegrpo/resolve/main/src/data/diff_utils.py
- Command line
-
hf download hf://Dhruv1000/tracegrpo/src/data/diff_utils.py
-
curl -L -o diff_utils.py https://huggingface.co/Dhruv1000/tracegrpo/resolve/main/src/data/diff_utils.py
1.67 kB
| """Shared diff-to-patch-lines logic (spec §3.2's `patch_lines_vuln`), used by | |
| every source loader so patch line numbers are always relative to the | |
| extracted function body itself — never to the original file's absolute line | |
| numbers. See DECISIONS.md "SecVulEval patch-line numbers were file-absolute, | |
| not function-relative" for why this needed to be a shared, source-agnostic | |
| computation rather than trusting any one dataset's own line-number field. | |
| """ | |
| from __future__ import annotations | |
| import difflib | |
| def diff_and_patch_lines(func_vuln: str, func_patch: str) -> tuple[str, list[int]]: | |
| """Unified diff of the function pair + 1-based line numbers in func_vuln | |
| that were removed/changed by the patch (spec §3.2 `patch_lines_vuln`). | |
| A pure insertion (e.g. a missing null-check added, CWE-476/CWE-20 style | |
| fixes) has no line in func_vuln that was literally changed, but the | |
| patch location is still meaningful for localization: we anchor to the | |
| line immediately preceding the insertion point (1-based), or line 1 if | |
| the insertion is at the very top. | |
| """ | |
| vuln_lines = func_vuln.splitlines(keepends=True) | |
| patch_lines = func_patch.splitlines(keepends=True) | |
| diff = "".join( | |
| difflib.unified_diff(vuln_lines, patch_lines, fromfile="vuln", tofile="patch") | |
| ) | |
| changed: set[int] = set() | |
| sm = difflib.SequenceMatcher(a=vuln_lines, b=patch_lines, autojunk=False) | |
| for tag, i1, i2, _j1, _j2 in sm.get_opcodes(): | |
| if tag in ("replace", "delete"): | |
| changed.update(range(i1 + 1, i2 + 1)) # 1-based | |
| elif tag == "insert": | |
| changed.add(max(1, i1)) | |
| return diff, sorted(changed) | |