Nomearod Claude Opus 4.6 (1M context) commited on
Commit
7d3f664
·
1 Parent(s): f665498

fix(security): strip punctuation before slashes in URL normalization

Browse files

_normalize_url() was stripping "/" then ".,;:", so a captured URL like
"https://x.com/." normalized to "https://x.com/" instead of
"https://x.com", causing grounded URLs to be flagged as hallucinated.
Reversed the order: strip punctuation first, then trailing slashes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

agent_bench/security/output_validator.py CHANGED
@@ -62,8 +62,8 @@ class OutputValidator:
62
 
63
  @staticmethod
64
  def _normalize_url(url: str) -> str:
65
- """Strip trailing slashes and punctuation for comparison."""
66
- return url.rstrip("/").rstrip(".,;:")
67
 
68
  def _check_urls(self, output: str, retrieved_chunks: list[str]) -> list[str]:
69
  url_pattern = re.compile(r"https?://[^\s\)\"'>]+")
 
62
 
63
  @staticmethod
64
  def _normalize_url(url: str) -> str:
65
+ """Strip trailing punctuation then trailing slashes for comparison."""
66
+ return url.rstrip(".,;:").rstrip("/")
67
 
68
  def _check_urls(self, output: str, retrieved_chunks: list[str]) -> list[str]:
69
  url_pattern = re.compile(r"https?://[^\s\)\"'>]+")
tests/test_output_validator.py CHANGED
@@ -73,6 +73,15 @@ class TestURLValidation:
73
  assert verdict.passed is True
74
  assert verdict.violations == []
75
 
 
 
 
 
 
 
 
 
 
76
  def test_trailing_slash_normalization_reverse(self, validator):
77
  """Chunk without slash, output with slash."""
78
  chunks = ["Visit https://fastapi.tiangolo.com for docs."]
 
73
  assert verdict.passed is True
74
  assert verdict.violations == []
75
 
76
+ def test_trailing_slash_with_sentence_punctuation(self, validator):
77
+ """Chunk URL followed by period: 'https://x.com/.' must match 'https://x.com/'."""
78
+ chunks = ["Visit https://fastapi.tiangolo.com/."]
79
+ verdict = validator.validate(
80
+ output="See https://fastapi.tiangolo.com/ for details.",
81
+ retrieved_chunks=chunks,
82
+ )
83
+ assert verdict.passed is True
84
+
85
  def test_trailing_slash_normalization_reverse(self, validator):
86
  """Chunk without slash, output with slash."""
87
  chunks = ["Visit https://fastapi.tiangolo.com for docs."]