(cand: Dict[str, Any])
| 1400 | removed_norm = _norm("\n".join(removed)) |
| 1401 | |
| 1402 | def _intersects_diff(cand: Dict[str, Any]) -> bool: |
| 1403 | vc_raw = " ".join(str(cand.get("vulnerableCode") or "").split()) |
| 1404 | vc = _norm(vc_raw) |
| 1405 | if len(vc) < 8: |
| 1406 | return True |
| 1407 | # 1) vc 3-gram appears in + lines (original check, now symmetric norm) |
| 1408 | toks = vc.split() |
| 1409 | for i in range(max(1, len(toks) - 2)): |
| 1410 | if " ".join(toks[i:i + 3]) in added_norm: |
| 1411 | return True |
| 1412 | # 2) any individual + line (≥8 chars) is contained in vc — handles |
| 1413 | # "investigate cites whole block, diff added one list item" |
| 1414 | for ln in added: |
| 1415 | ln_n = _norm(ln) |
| 1416 | if len(ln_n) >= 8 and ln_n in vc: |
| 1417 | return True |
| 1418 | # 3) deletion-aware: vc tokens match REMOVED lines and there are |
| 1419 | # fewer + than - lines in the diff — vuln introduced by removing |
| 1420 | # a guard. Keep so self-refute can adjudicate. |
| 1421 | if len(added) < len(removed): |
| 1422 | for i in range(max(1, len(toks) - 2)): |
| 1423 | if " ".join(toks[i:i + 3]) in removed_norm: |
| 1424 | return True |
| 1425 | return False |
| 1426 | |
| 1427 | # SOFT intersect: tag instead of drop. Non-intersecting candidates |
| 1428 | # reach self-refute with a `_diff_anchor` flag so the refute pass |
no test coverage detected