Repository navigation
fix: reject values at or above 2^63 in int parameter parsing - #3493
xiao115255 wants to merge 4 commits into
Conversation
toInt's upper bound compares against math.MaxInt, which is 2^(strconv.IntSize-1) - 1 and cannot be represented as a float64: on 64-bit targets it rounds up to exactly 2^63, so a value that parses to 2^63 is not greater than the bound and passed the check. It then reached int(f), and converting an out-of-range float64 to int is implementation-defined - MinInt on amd64 - so the parameter was accepted and a large negative number was sent to the API instead of failing the range check. That covered every caller of RequiredInt, OptionalIntParam, OptionalIntParamWithDefault and OptionalPaginationParams, including the string "9223372036854775807", which ParseFloat rounds to 2^63. Compare against math.Ldexp(1, strconv.IntSize-1) instead. It is the exact power of two on both 32- and 64-bit targets, so the bound holds everywhere and the conversion is never reached with an out-of-range value - unlike inspecting the result of the conversion, which only catches the overflow on targets that do not saturate.
IrynaKulakova
left a comment
There was a problem hiding this comment.
The exact power-of-two bound correctly rejects out-of-range values before conversion while preserving the inclusive lower bound. Verified on macOS arm64: script/lint and the full race-enabled script/test suite passed. Additional boundary checks passed for string and float inputs through required, optional, and defaulted integer helpers. No blocking findings.
There was a problem hiding this comment.
🟡 Changes recommended
A misplaced closing brace prevents pkg/github from compiling, and the boundary test omits its input map, causing its error assertion to fail.
2 open issues
What changed in this PR
This PR targets #3489: rejecting numeric inputs that round to 2^63 before converting them to int in shared GitHub tool parameter parsing.
Changes:
- Modifies the range-check block in
toInt. - Updates
OptionalIntParamboundary tests, replacing the MinInt acceptance case with MaxInt32.
| File | Description |
|---|---|
pkg/github/params.go |
Changes range validation before integer conversion. |
pkg/github/params_test.go |
Adjusts float64 boundary inputs and expected results. |
Review effort: Balanced (auto)
| return 0, fmt.Errorf("non-integer numeric value: %v", f) | ||
| } | ||
| if !inSignedIntRange(f, strconv.IntSize) { | ||
| return 0, fmt.Errorf("numeric value out of int range: %v", f) |
| { | ||
| name: "2^63 float64 parameter", | ||
| params: map[string]any{"count": math.Ldexp(1, 63)}, | ||
| paramName: "count", |

Summary
toIntbounded its upper range withmath.MaxInt, which a float64 cannot represent: it rounds up to exactly 2^63, so a value that parses to 2^63 was not greater than the bound and passed. It then reachedint(f), and that conversion is implementation-defined for an out-of-range value (MinInt on amd64). Compare against the exact power of two instead, before converting.Why
Fixes #3489
What changed
pkg/github/params.go: the range check intoIntnow usesmath.Ldexp(1, strconv.IntSize-1)and runs before the conversion, so the bound is exact on 32- and 64-bit targets andint(f)is never reached with an out-of-range value.pkg/github/params_test.go: boundary cases throughOptionalIntParam— 2^63 and"9223372036854775807"(whichParseFloatrounds to 2^63) are rejected, as a string and as a float64, whilemath.MaxInt32is still accepted.MCP impact
Prompts tested (tool changes only)
Security / limits
Rejected values used to pass locally and reach the API as large negative integers (
issue_number,pull_number,page,perPage). They now fail the range check before the request is built. The error message is unchanged.Tool renaming
Lint & tests
./script/lint./script/testgo test ./pkg/githubpasses the changed tests, and the three new rejection cases fail with the fix reverted.gofmt -s -landgo vetreport nothing on either file. I did not runscript/lint(golangci-lint is not installed on this machine) or the fullscript/test; on this Windows checkout the whole./pkg/githubpackage reports 14 failures in tool-snapshot tests (icon\rmismatches) that are identical on the parent commit.Docs
The same
parsed > float64(math.MaxInt)check is duplicated insecurity_outputs.goandtyped_read_normalizers.go. Happy to send that as a separate PR.