diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 7b8ad8b2..4b43f974 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -281,6 +281,11 @@ func ParsePercentageRatio(source string) (*big.Int, uint16, error) { scale = len(source) - i - 1 } + // Validate scale is reasonable (max 18 decimal places) + if scale > 18 { + return nil, 0, fmt.Errorf("percentage has too many decimal places (%d), maximum is 18", scale) + } + intPart := strings.ReplaceAll(source, ".", "") num, ok := new(big.Int).SetString(intPart, 10) if !ok { diff --git a/internal/parser/percentage_fuzz_test.go b/internal/parser/percentage_fuzz_test.go new file mode 100644 index 00000000..b6f65d1e --- /dev/null +++ b/internal/parser/percentage_fuzz_test.go @@ -0,0 +1,45 @@ +package parser + +import ( + "testing" +) + +func FuzzParsePercentageRatio(f *testing.F) { + // Seed corpus with valid and edge case percentages + f.Add("0%") + f.Add("100%") + f.Add("50%") + f.Add("50.5%") + f.Add("0.1%") + f.Add("99.99%") + f.Add("1%") + f.Add("10.0%") + f.Add("33.333%") + f.Add("100.00%") + f.Add("0.0%") + // Invalid cases to test error handling + f.Add("101%") + f.Add("-5%") + f.Add("abc%") + f.Add("%") + f.Add("50") + f.Add("50.%") + f.Add(".50%") + + f.Fuzz(func(t *testing.T, input string) { + // Call ParsePercentageRatio and ensure it doesn't panic + num, floatingDigits, err := ParsePercentageRatio(input) + + if err == nil { + // If parsing succeeded, verify the result is reasonable + if num == nil { + t.Errorf("ParsePercentageRatio succeeded but returned nil num for input: %q", input) + } + // Note: negative numbers are allowed - the parser doesn't enforce constraints + // Floating digits should be limited to 18 (now enforced by the parser) + if floatingDigits > 18 { + t.Errorf("ParsePercentageRatio returned floatingDigits=%d > 18 for input: %q", floatingDigits, input) + } + } + }) +} diff --git a/internal/parser/testdata/fuzz/FuzzParsePercentageRatio/98e3857fbdb2cc2c b/internal/parser/testdata/fuzz/FuzzParsePercentageRatio/98e3857fbdb2cc2c new file mode 100644 index 00000000..ba9ef7ae --- /dev/null +++ b/internal/parser/testdata/fuzz/FuzzParsePercentageRatio/98e3857fbdb2cc2c @@ -0,0 +1,2 @@ +go test fuzz v1 +string("0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")