Repository navigation
Fix u64 underflow in binom() when k > n - #1075
Open
newmathphys wants to merge 1 commit into
Open
newmathphys wants to merge 1 commit into
newmathphys wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1075 +/- ##
==========================================
- Coverage 95.89% 95.89% -0.01%
==========================================
Files 396 396
Lines 30441 30448 +7
==========================================
+ Hits 29192 29197 +5
- Misses 1249 1251 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
newmathphys
pushed a commit
to newmathphys/kern
that referenced
this pull request
Oct 22, 2026
Second real defect found in a third-party repository, and the second upstream report from this project. PR: TheAlgorithms/Rust#1075 (+16 -0, one file) - guard `if k > n { return BigInt::from(0) }` in binom() - regression test `test_binom_k_greater_than_n` so the repository's own CI covers the case from now on The fix was verified before submitting: all seven existing expectations still hold (binom(5,2)=10, binom(10,5)=252, binom(0,0)=1, binom(1000,2)=499500, binom(7,4)=35, binom(12,3)=220, binom(20,10)=184756) and the three failing inputs now return 0 instead of panicking or returning garbage. Recorded in the journal entry #324 (RU + EN), the plan (step 7) and both READMEs. Evidence: docs/evidence/thealgorithms_rust/ - the verbatim upstream file, the shadow contract, the ground-truth program and log, the fixed file, the PR body and the fix-verification log. Gates: ci-fast 10/10, metrics-guard, llms-check, sync-check, docs-parity, evidence-gate, secrets-check.
newmathphys
pushed a commit
to newmathphys/kern
that referenced
this pull request
Oct 22, 2026
newmathphys
pushed a commit
to newmathphys/kern
that referenced
this pull request
Oct 22, 2026
…s tracking
DEFECT #330. The .gitignore exception
!docs/evidence/*.log
applies ONLY to the TOP LEVEL of the directory. Logs in SUBdirectories -
`div_guards/`, `leaderboard/`, `live_eval/`, `arith_semantics/`, `external/`,
`claims_audit/`, `megatest/`, `full_arsenal/`, `prime_sieve/`, `step4_while/`,
`step8_evm/`, `live_bughunt/` - were silently ignored, so 46 files that the
documentation LINKS TO were not in the repository. An external auditor who
followed such a link got a 404: the prose promised evidence that did not exist.
Measured before the fix:
git check-ignore -v docs/evidence/external/verification.log
-> .gitignore:54:*.log
files on disk under docs/evidence/ but NOT in git: 46
That is the same class as #320 (a claim without a command that reproduces it),
which is why it matters more than a missing file usually would.
FIX
* .gitignore: added `!docs/evidence/**/*.log` (plus .json, .txt, .jsonl)
with a comment explaining WHY the single-star version was not enough;
* all 46 files staged;
* tools/evidence_gate.py now walks docs/evidence/ RECURSIVELY and fails when
any file there is not tracked, printing the list and the exact .gitignore
remedy.
NON-VACUITY: `git rm --cached` of one log turns the gate red (rc=2), then the
file is restored and the gate is green again.
A HARNESS DEFECT FOUND BY RUNNING THE CASE. The first version of the can-fail
case did `git rm --cached` and left it there. The harness rolls back FILES from
its snapshot but does not touch the INDEX, so after one run the log stayed
untracked and `evidence-gate` was red permanently - the case broke the next
run. The case is now self-healing: it removes the file from the index, runs the
gate, restores the index in the same shell command, and returns the GATE's exit
code, not `git add`'s. Verified: PASS, non-vacuous, index clean afterwards.
ALSO IN THIS COMMIT (step B, remaining items)
docs/evidence/external/verification.log - what OUTSIDE parties confirmed:
Codecov on TheAlgorithms/Rust#1075: ci_passed true, base 30441 lines /
95.89% -> head 30448 / 95.89%, "all modified and coverable lines are
covered by tests";
TheAlgorithms/C#1595 open, mergeable, +7/-0, 0 comments;
TheAlgorithms/Rust#1075 open, mergeable, +16/-0, 1 comment (the Codecov
bot; no maintainer response yet);
release v2.6.4 draft=false with 4 assets INCLUDING kern.intoto.jsonl and
kern.intoto.sig, so the binary can be verified against the public key.
Registry: 191 targets, CHECK 152/152, 174 can-fail cases.
Gates: ci-fast, claims-audit, evidence-gate, metrics-guard, llms-check,
sync-check, docs-parity, version-check, secrets-check, contracts, audits,
codecheck - all green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
binom(n, k)underflowsu64whenk > n: the loop runs fori in 0..k, soit evaluates
n - ifori > n.All seven existing tests use
k <= n, so the case is not covered:test_binom_5_2test_binom_10_5test_binom_0_0test_binom_large_n_small_ktest_binom_random_1test_binom_random_2test_binom_random_3Mathematically
C(n, k) = 0fork > n, so the function should return0rather than panic or return garbage.
The fix
Guard the case explicitly and keep the rest unchanged:
pub fn binom(n: u64, k: u64) -> BigInt { + // C(n, k) = 0 for k > n. Without this guard the loop below evaluates + // `n - i` for i > n, which is invalid for u64: a debug build panics with + // "attempt to subtract with overflow", and a release build silently wraps + // to 18446744073709551615 and returns garbage instead of 0. + if k > n { + return BigInt::from(0); + } + let mut res = BigInt::from_u64(1).unwrap();A regression test is added in the same commit, so CI covers the case:
Verification
The guard was checked against the seven existing expectations (no regression)
and against the three failing inputs, using the same arithmetic as the function
body:
How this was found
Not by reading the code: by stating a contract for the expression
n - iwiththe loop's own condition (
requires i < k,ensures result >= 0) and letting aSMT solver refute it. The counterexample was
n = 0, i = 1— reachable asbinom(0, 2)— and was then reproduced withrustc(panic in debug, wrappedgarbage in release). See KERN, which
documents the case.
Happy to adjust the style (for example, documenting
k <= nas a preconditioninstead of returning 0) if you prefer that contract.