Conversation
copy_poly_in_matrixcol_no_zero, used by the sparse-FGLM-col algorithm (option -C), copied the coefficients of a polynomial into the multiplication matrix with two defects. First, the index k walking through the tail of the polynomial was bounded by end, a position in the whole coefficient array, instead of by the length pos of the polynomial. Hence k could go past the tail to the leading term and then to the terms of the previous polynomial, whose coefficients could be written into the row. Second, is_larger_exponent, used to compare a tail term with the monomials of the basis, stopped its tie-breaking loop at x_2, so that monomials of the same degree which differ only in x_0 and x_1 were considered equal; e.g. with two variables, all monomials of the same degree were. The same loop is fixed in is_larger_exponent_bs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wegank
marked this pull request as draft
October 1, 2026 23:49
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.
This fixes two defects in
copy_poly_in_matrixcol_no_zero, which builds the multiplication matrix for the sparse-FGLM-col algorithm (option-C).Tail bound
The index
kwalks through the tail of the polynomial from its smallest term, at indexend - 1 - k. It was bounded byend, a position in the whole coefficient array, instead of by the lengthposof the polynomial. Hence, when the polynomial is not the first one in the array,kcould go past the tail to the leading term and then to the terms of the previous polynomial, whose coefficients could then be written into the row. The memory is valid, so AddressSanitizer does not detect it. The bounds are nowk < pos - 1andk < pos - 2.Monomial comparison
is_larger_exponentbreaks ties between monomials of the same degree withfor (i = nvars-1; i>1; i--), so it never compares the exponents ofx_1(and hencex_0). Monomials of the same degree which differ only inx_0andx_1were thus considered equal; with two variables, all monomials of the same degree were. The loop now goes down toi = 1, which suffices since the degrees are equal. The same loop is fixed inis_larger_exponent_bs, used bycopy_extrapoly_in_vector_no_zeroandcopy_extrapoly_in_matrixcol_no_zero, also in the-Cpath.Testing
No test in
make checkreaches this code, and the-Cpath currently crashes before it on every system I tried (see below). I therefore tested the function directly with a small harness, callingcopy_poly_in_matrixcol_no_zeroon hand-built data where the target polynomial follows another polynomial in the array:y^2 - x, 2 variablesxin theycolumnz^2 + 3x + 7z + 11(noy), 3 variablesxin theycolumnmake checkpasses (68/68) with a normal-O2build.Remaining issues in the
-Cpath (not addressed here)src/msolve/msolve.c:4305readstbr->lmps[1]whiletbr->lml == 1; under AddressSanitizer every zero-dimensional system I generated crashes there.src/msolve/msolve.c:4189allocatesmulwithgens->nvarsentries, whileinsert_multiplied_poly_in_hash_tablereadsht->evl = nvars + 1of them (line 4636 usesbht->evl).src/neogb/nf.c:40uses the same size; I have not checked whether it is read past its end there.copy_extrapoly_*_no_zerofunctions,while (b < 0 && k < len-2)looks one short, but I have not confirmed it.Related: #379 fixes a similar out-of-bounds read in
copy_poly_in_matrix(default path); the two changes are independent.This change was made with the assistance of generative AI (Claude Code).
Co-authored-by: Claude Opus 5.5 noreply@anthropic.com
🤖 Generated with Claude Code