Skip to content

Commit 7cbf8cd

Browse files
fix benchmark evidence size integrity
1 parent 413e384 commit 7cbf8cd

4 files changed

Lines changed: 107 additions & 13 deletions

File tree

benchmarks/datasets/mathematical-benchmarks-v1/exact-farkas-ldl-slice/tests/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FROM python:3.12-slim@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de
22
RUN python -m pip install --no-cache-dir attrs==26.1.0 jsonschema==4.26.0 jsonschema-specifications==2025.9.1 referencing==0.37.0 rpds-py==2026.6.3 typing-extensions==4.16.0
3-
LABEL jacobian.checksum="63ab71931d2312ef7d7a296f3caf1d2ae40024e783be96c302d3e151338b84dd"
3+
LABEL jacobian.checksum="6036fee901aab3df23258e3cbbbaa97da624f0bbd14ae34d0602d58927ad0a1e"
44
LABEL jacobian.task="jacobian/exact-farkas-ldl-slice"
55
COPY expected.json input.json test.sh verifier.py verifier_support.py public_contract.json /tests/
66
COPY input.json /app/input.json

benchmarks/datasets/mathematical-benchmarks-v1/exact-farkas-ldl-slice/tests/verifier.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
W, E = Path("/app"), Path("/tests")
1616
MAX_INPUT_BYTES = 1_048_576
1717
MAX_SUBMISSION_BYTES = 1_048_576
18-
MAX_EVIDENCE_BYTES = 1_048_576
1918

2019

2120
def _load_frozen():
@@ -198,12 +197,10 @@ def main():
198197
and isinstance(submission.get("evidence"), list)
199198
and len(submission["evidence"]) == 1
200199
):
201-
evidence_path = W / "evidence" / "farkas-slice-certificate.json"
202-
if is_regular_bounded_file(evidence_path, max_bytes=MAX_EVIDENCE_BYTES):
203-
evidence = read_evidence_json(
204-
submission["evidence"][0],
205-
expected_path="evidence/farkas-slice-certificate.json",
206-
)
200+
evidence = read_evidence_json(
201+
submission["evidence"][0],
202+
expected_path="evidence/farkas-slice-certificate.json",
203+
)
207204
evidence_valid = bool(
208205
evidence
209206
and set(evidence) == {"schema_version", "task_id", "result", "limitations"}

benchmarks/datasets/mathematical-benchmarks-v1/exact-farkas-ldl-slice/tests/verifier_support.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import codecs
56
import hashlib
67
import json
78
import math
@@ -262,14 +263,57 @@ def resolve_evidence(
262263
return target
263264

264265

266+
_JSON_WHITESPACE = frozenset(" \t\n\r")
267+
_JSON_WHITESPACE_CHARS = " \t\n\r"
268+
269+
270+
def _drain_stream_tail(stream, decoder) -> None:
271+
"""Reject any non-whitespace content after the parsed JSON value."""
272+
273+
while True:
274+
block = stream.read(65_536)
275+
if not block:
276+
break
277+
tail = decoder.decode(block)
278+
if tail and not all(character in _JSON_WHITESPACE for character in tail):
279+
raise ValueError("non-whitespace after evidence JSON value")
280+
tail = decoder.decode(b"", final=True)
281+
if tail and not all(character in _JSON_WHITESPACE for character in tail):
282+
raise ValueError("non-whitespace after evidence JSON value")
283+
284+
285+
def _read_streaming_json_value(stream) -> Any:
286+
"""Parse one JSON value without retaining arbitrary whitespace padding."""
287+
288+
decoder = codecs.getincrementaldecoder("utf-8")()
289+
parser = json.JSONDecoder(object_pairs_hook=_reject_duplicate_keys)
290+
buffer = ""
291+
while True:
292+
block = stream.read(65_536)
293+
if block:
294+
buffer += decoder.decode(block)
295+
if buffer[:1] in _JSON_WHITESPACE:
296+
buffer = buffer.lstrip(_JSON_WHITESPACE_CHARS)
297+
try:
298+
value, end = parser.raw_decode(buffer)
299+
except json.JSONDecodeError:
300+
if not block:
301+
raise
302+
continue
303+
if not all(character in _JSON_WHITESPACE for character in buffer[end:]):
304+
raise ValueError("non-whitespace after evidence JSON value")
305+
_drain_stream_tail(stream, decoder)
306+
return value
307+
308+
265309
def read_evidence_json(
266310
descriptor: object,
267311
*,
268312
expected_path: str,
269313
workspace: Path = WORKSPACE,
270314
max_bytes: int | None = None,
271315
) -> dict[str, Any] | None:
272-
"""Resolve and parse a digest-bound evidence object."""
316+
"""Resolve and stream a digest-bound evidence object without a byte cap."""
273317

274318
target = resolve_evidence(
275319
descriptor,
@@ -280,10 +324,8 @@ def read_evidence_json(
280324
if target is None:
281325
return None
282326
try:
283-
value = json.loads(
284-
target.read_text(),
285-
object_pairs_hook=_reject_duplicate_keys,
286-
)
327+
with target.open("rb") as stream:
328+
value = _read_streaming_json_value(stream)
287329
except (OSError, ValueError, RecursionError, MemoryError):
288330
return None
289331
return value if isinstance(value, dict) else None

benchmarks/validation/mathematical_benchmarks_v1/test_exact_farkas_ldl_slice.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,58 @@ def test_exact_farkas_slice_rejects_missing_evidence_envelope(tmp_path: Path) ->
139139
rejected = support._run_verifier(task, app, logs)
140140
assert rejected.details["evidence_validity"] == 0.0
141141
assert rejected.reward == 0.0
142+
143+
144+
def test_exact_farkas_slice_accepts_large_valid_evidence_padding(
145+
tmp_path: Path,
146+
) -> None:
147+
"""Legal JSON whitespace must not create a hidden evidence-size limit."""
148+
task, app, logs = _prepare_farkas_slice_case(tmp_path)
149+
submission = json.loads((app / "submission.json").read_text())
150+
evidence_path = app / "evidence" / "farkas-slice-certificate.json"
151+
evidence_path.write_text(
152+
" \n" * (600 * 1024)
153+
+ json.dumps(
154+
{
155+
"schema_version": "1",
156+
"task_id": submission["task_id"],
157+
"result": submission["result"],
158+
"limitations": submission["limitations"],
159+
},
160+
sort_keys=True,
161+
separators=(",", ":"),
162+
)
163+
+ "\n"
164+
+ " " * (600 * 1024)
165+
)
166+
submission["evidence"][0]["sha256"] = support._digest(evidence_path)
167+
support._write_json(app / "submission.json", submission)
168+
169+
accepted = support._run_verifier(task, app, logs)
170+
assert accepted.details["evidence_validity"] == 1.0
171+
assert accepted.reward == pytest.approx(1.0)
172+
173+
174+
@pytest.mark.parametrize("prefix,suffix", [("garbage", ""), ("", "garbage")])
175+
def test_exact_farkas_slice_rejects_evidence_json_garbage(
176+
tmp_path: Path,
177+
prefix: str,
178+
suffix: str,
179+
) -> None:
180+
"""Streaming acceptance must still reject content outside the JSON value."""
181+
task, app, logs = _prepare_farkas_slice_case(tmp_path)
182+
submission = json.loads((app / "submission.json").read_text())
183+
evidence_path = app / "evidence" / "farkas-slice-certificate.json"
184+
payload = {
185+
"schema_version": "1",
186+
"task_id": submission["task_id"],
187+
"result": submission["result"],
188+
"limitations": submission["limitations"],
189+
}
190+
evidence_path.write_text(prefix + json.dumps(payload) + suffix)
191+
submission["evidence"][0]["sha256"] = support._digest(evidence_path)
192+
support._write_json(app / "submission.json", submission)
193+
194+
rejected = support._run_verifier(task, app, logs)
195+
assert rejected.details["evidence_validity"] == 0.0
196+
assert rejected.reward == 0.0

0 commit comments

Comments
 (0)