Skip to content

Fix #202, #203, #204: close scoring exploits in problems 112, 107 and 28 - #206

Merged
joyemang33 merged 1 commit into
FrontierCS:mainfrom
whuang369:fix/202-204-checker-exploits
Oct 31, 2026
Merged

joyemang33 merged 1 commit into
FrontierCS:mainfrom
whuang369:fix/202-204-checker-exploits

Conversation

@whuang369

Copy link
Copy Markdown
Contributor

Each issue lets a submission that does no real work score 100.

#202, problem 112 checker: testlib reads an overflowing literal such as 1e400 as inf. The relative tolerance test |actual - claimed| <= 1e-6 * max(1, |actual|, |claimed|) then compares inf with inf and passes for any placement, even with every point at the origin, and the score caps at 100. Reject a claimed distance that is not finite. An infinite coordinate needs no extra check, because the unit sphere test already rejects it.

#203, problem 107 interactor: the guess d was compared in 32-bit int, so 2 * d overflows for a guess such as -1500000000 (in practice it wraps to 1294967296) and the factor-of-two test passes without any query. Compare in 64 bits. Also print the out-of-range query value with %lld instead of %d.

#204, problem 28 interactor: the answer check only required each word to be at most the last dictionary word with the same first letter and never checked that the word is in the dictionary, so "answer a0 a1 ... a999" with no query scored 100. Check each answered word against the dictionary. Repeats are already rejected, so n accepted words are the whole dictionary; an ensuref checks that the word lists hold exactly n words.

The first character of a query prefix or answer word also indexed s[] and num[] without a bounds check, so "query 0a 1" or an answer word starting with 'A' crashed the interactor. A prefix that does not start with a lowercase letter now matches nothing, as '{' to '~' already did.

Verdicts and scores for valid play are unchanged.

Verified in the frontier-cs-judge image (g++ 11.4, -O2 -std=gnu++17): all 42 new tests in algorithmic/tests/test_problem{28,107,112}.py pass, and on main the 12 that reproduce the exploits and crashes fail. The other 30 pass on both, including problem 107's error bounds and the full dictionary of each problem 28 test (ratio 1).

Fixes #202, fixes #203, fixes #204.

Summary

Please read CONTRIBUTING.md before submitting.

Type of Change

  • New research problem
  • New algorithmic problem
  • New Frontier-CS 2.0 problem
  • Bug fix
  • Documentation update
  • Other:

Testing

Checklist

  • Code follows the project structure and conventions
  • Self-review completed
  • Documentation updated (if applicable)

CI Validation (for new problems)

When adding new problems, CI will automatically validate that your reference solution achieves score > 0.

  • Algorithmic problems: Include reference.cpp in your problem directory
  • Research problems: Include reference.py (or reference.cpp if language: cpp in config.yaml)
  • 2.0 problems: Include reference.py unless the problem config declares another language

…loits in problems 112, 107 and 28

Each issue lets a submission that does no real work score 100.

FrontierCS#202, problem 112 checker: testlib reads an overflowing literal such as
1e400 as inf. The relative tolerance test |actual - claimed| <= 1e-6 *
max(1, |actual|, |claimed|) then compares inf with inf and passes for
any placement, even with every point at the origin, and the score caps
at 100. Reject a claimed distance that is not finite. An infinite
coordinate needs no extra check, because the unit sphere test already
rejects it.

FrontierCS#203, problem 107 interactor: the guess d was compared in 32-bit int,
so 2 * d overflows for a guess such as -1500000000 (in practice it
wraps to 1294967296) and the factor-of-two test passes without any
query. Compare in 64 bits. Also print the out-of-range query value
with %lld instead of %d.

FrontierCS#204, problem 28 interactor: the answer check only required each word
to be at most the last dictionary word with the same first letter and
never checked that the word is in the dictionary, so "answer a0 a1 ...
a999" with no query scored 100. Check each answered word against the
dictionary. Repeats are already rejected, so n accepted words are the
whole dictionary; an ensuref checks that the word lists hold exactly n
words.

The first character of a query prefix or answer word also indexed s[]
and num[] without a bounds check, so "query 0a 1" or an answer word
starting with 'A' crashed the interactor. A prefix that does not start
with a lowercase letter now matches nothing, as '{' to '~' already
did.

Verdicts and scores for valid play are unchanged.

Verified in the frontier-cs-judge image (g++ 11.4, -O2 -std=gnu++17):
all 42 new tests in algorithmic/tests/test_problem{28,107,112}.py pass,
and on main the 12 that reproduce the exploits and crashes fail. The
other 30 pass on both, including problem 107's error bounds and the
full dictionary of each problem 28 test (ratio 1).

Fixes FrontierCS#202, fixes FrontierCS#203, fixes FrontierCS#204.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@joyemang33
joyemang33 merged commit f7f7a18 into FrontierCS:main Oct 31, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants