diff --git a/decimal.go b/decimal.go index 6244825..775c417 100644 --- a/decimal.go +++ b/decimal.go @@ -156,6 +156,11 @@ func (d *Decimal) setString(c *Context, s string) (Condition, error) { exps = append(exps, -exp) s = s[:i] + s[i+1:] } + for _, ch := range s { + if ch < '0' || ch > '9' { + return 0, fmt.Errorf("parse mantissa: %s", s) + } + } if _, ok := d.Coeff.SetString(s, 10); !ok { return 0, fmt.Errorf("parse mantissa: %s", s) } diff --git a/decimal_test.go b/decimal_test.go index bc00e04..cda8926 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -964,3 +964,33 @@ func TestJSONEncoding(t *testing.T) { } } } + +// TestNewFromStringInvalid tests that NewFromString produces +// an error when parsing an invalid decimal. +func TestNewFromStringInvalid(t *testing.T) { + tests := []struct { + input string + }{ + {input: ".-5"}, + {input: ".+5"}, + {input: ".-0"}, + {input: ".+0"}, + {input: ".-123"}, + {input: ".+123"}, + {input: "1.-2"}, + {input: "1.+2"}, + {input: ".1-2"}, + {input: ".1+2"}, + {input: ".-5e1"}, + {input: ".+5e1"}, + } + for _, tc := range tests { + t.Run(tc.input, func(t *testing.T) { + d, _, err := NewFromString(tc.input) + if err == nil { + t.Fatalf("expected error for %q, but parsed as: %s (Negative=%v, Coeff=%s)", + tc.input, d.String(), d.Negative, d.Coeff.String()) + } + }) + } +}