Skip to content

fix: reject values at or above 2^63 in int parameter parsing - #3493

Open
xiao115255 wants to merge 1 commit into
github:mainfrom
xiao115255:fix/params-toint-int-range
Open

xiao115255 wants to merge 1 commit into
github:mainfrom
xiao115255:fix/params-toint-int-range

Conversation

@xiao115255

Copy link
Copy Markdown

Summary

toInt bounded its upper range with math.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 reached int(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 in toInt now uses math.Ldexp(1, strconv.IntSize-1) and runs before the conversion, so the bound is exact on 32- and 64-bit targets and int(f) is never reached with an out-of-range value.
  • pkg/github/params_test.go: boundary cases through OptionalIntParam — 2^63 and "9223372036854775807" (which ParseFloat rounds to 2^63) are rejected, as a string and as a float64, while math.MaxInt32 is still accepted.

MCP impact

  • No tool or API changes

Prompts tested (tool changes only)

Security / limits

  • No security or limits impact

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

  • I am not renaming tools as part of this PR

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

go test ./pkg/github passes the changed tests, and the three new rejection cases fail with the fix reverted. gofmt -s -l and go vet report nothing on either file. I did not run script/lint (golangci-lint is not installed on this machine) or the full script/test; on this Windows checkout the whole ./pkg/github package reports 14 failures in tool-snapshot tests (icon \r mismatches) that are identical on the parent commit.

Docs

  • Not needed

The same parsed > float64(math.MaxInt) check is duplicated in security_outputs.go and typed_read_normalizers.go. Happy to send that as a separate PR.

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.
@xiao115255
xiao115255 requested a review from a team as a code owner October 13, 2026 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integer parameters equal to 2^63 pass the range check in toInt and wrap to a negative number

1 participant