Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion pkg/github/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,14 @@ func toInt(val any) (int, error) {
if f != math.Trunc(f) {
return 0, fmt.Errorf("non-integer numeric value: %v", f)
}
if f > math.MaxInt || f < math.MinInt {
// Compare before converting, against the exact power of two. math.MaxInt is
// 2^(strconv.IntSize-1) - 1, which a float64 cannot represent: on 64-bit
// targets it rounds up to exactly 2^63, so comparing against it lets 2^63
// through. Converting an out-of-range float64 to int is implementation-defined
// - MinInt on amd64, MaxInt on the targets whose conversion saturates - so the
// bound has to reject the value before the conversion rather than inspect the
// result of it. math.Ldexp gives the exact bound on every target.
if limit := math.Ldexp(1, strconv.IntSize-1); f >= limit || f < -limit {
return 0, fmt.Errorf("numeric value out of int range: %v", f)
}
return int(f), nil
Expand Down
28 changes: 28 additions & 0 deletions pkg/github/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,34 @@ func Test_OptionalIntParam(t *testing.T) {
expected: 0,
expectError: true,
},
{
name: "2^63 string parameter",
params: map[string]any{"count": "9223372036854775808"},
paramName: "count",
expected: 0,
expectError: true,
},
{
name: "MaxInt64 string parameter rounds up to 2^63",
params: map[string]any{"count": "9223372036854775807"},
paramName: "count",
expected: 0,
expectError: true,
},
{
name: "2^63 float64 parameter",
params: map[string]any{"count": math.Pow(2, 63)},
paramName: "count",
expected: 0,
expectError: true,
},
{
name: "MaxInt32 float64 parameter",
params: map[string]any{"count": float64(math.MaxInt32)},
paramName: "count",
expected: math.MaxInt32,
expectError: false,
},
}

for _, tc := range tests {
Expand Down