Fix repeatString overflow test on 32-bit platforms (#2680)

The test literal "ab" * 4611686018427387904 (2^62) exceeds MaxInt32,
so parseInt rejects it before the size guard runs. Compute the count
with 1 << (bits.UintSize - 2) to yield 2^30 on 32-bit and 2^62 on
64-bit. Both values, when doubled by len("ab"), wrap past MaxInt and
bypass a naive len*count guard, exercising the division-safe check
added in #2644.

Signed-off-by: Jan Dubois <jan@jandubois.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jan Dubois 2026-04-25 16:18:34 -07:00 committed by GitHub
parent ff45fad14c
commit 1deec5e450
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,7 @@ package yqlib
import (
"fmt"
"math/bits"
"strings"
"testing"
)
@ -707,11 +708,13 @@ var multiplyOperatorScenarios = []expressionScenario{
expectedError: "result of repeating string (1 bytes) by 99999999 would exceed 10485760 bytes",
},
{
// The size guard must not overflow: len * count can wrap to
// a negative or small value on 64-bit, bypassing the check.
// Pick a count whose product with len("ab") overflows int on
// any architecture: 2^30 on 32-bit, 2^62 on 64-bit. Doubling
// either yields MaxInt+1, which wraps to MinInt and bypasses
// a naive len*count guard.
skipDoc: true,
expression: `"ab" * 4611686018427387904`,
expectedError: "result of repeating string (2 bytes) by 4611686018427387904 would exceed 10485760 bytes",
expression: fmt.Sprintf(`"ab" * %d`, 1<<(bits.UintSize-2)),
expectedError: fmt.Sprintf("result of repeating string (2 bytes) by %d would exceed 10485760 bytes", 1<<(bits.UintSize-2)),
},
}