some improvements

This commit is contained in:
mats committed 2026-07-03 19:30:32 +02:00
1 parent 9390f2132d
commit 4b9a882018
2 files changed
+121 -87

No files matched your search

+19
View File
@@ -78,6 +78,16 @@ func ParseCents(s string) (Cents, error) {
if intStr == "" {
intStr = "0"
}
// After the leading sign-strip above, the integer part must NOT contain a
// second sign character. strconv.ParseInt accepts a leading '-' or '+',
// which is how the previous "--1" bug silently flipped the sign (strip
// first '-', re-parse "-1" as -1, then `if neg { c = -c }` flipped it back
// to +100 — the wrong sign on the wrong input). Reject any second sign
// anywhere in the integer part: every malformed-sign input
// ("--1", "+-1", "-+1", "++1") now errors with ErrParse.
if strings.ContainsAny(intStr, "+-") {
return 0, fmt.Errorf("%w: %q has multiple signs in integer part", ErrParse, s)
}
// Pad the fractional part to exactly 2 digits: "5" → "50", "" → "00".
switch len(fracStr) {
case 0:
@@ -85,6 +95,15 @@ func ParseCents(s string) (Cents, error) {
case 1:
fracStr += "0"
}
// The fractional part must also be sign-free. A leading '-' on the
// fractional string ("-" alone, "-0") was previously parsed by ParseInt
// as 0 after the pad-to-2 above, which silently accepted inputs like
// ".-", "1.-", "1.-0". The fractional part is conventionally
// non-negative (the leading sign applies to the whole number); reject
// any sign anywhere in fracStr.
if strings.ContainsAny(fracStr, "+-") {
return 0, fmt.Errorf("%w: %q has a sign in fractional part", ErrParse, s)
}
major, err := strconv.ParseInt(intStr, 10, 64)
if err != nil {