fix(command): reject non-canonical decimals
- commit
- c082b4bc6f34459a07f784e980fc4ca8cfa04c49
- author
- brice · · 2026-07-11 13:00 UTC
- parent
- 0ac83ce
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +7 -1
M internal/usecase/command/command.go +1 -1
| @@ -11,7 +11,7 @@ var ErrInvalidArguments = errors.New("invalid command arguments") | |||
| 11 | 11 | // ParsePositiveDecimal accepts exactly one base-10 positive decimal value. | |
| 12 | 12 | // It deliberately rejects signs, whitespace, zero, and non-canonical forms. | |
| 13 | 13 | func ParsePositiveDecimal(args []string) (int, error) { | |
| 14 | - | if len(args) != 1 || args[0] == "" { | |
| 14 | + | if len(args) != 1 || args[0] == "" || (len(args[0]) > 1 && args[0][0] == '0') { | |
| 15 | 15 | return 0, ErrInvalidArguments | |
| 16 | 16 | } | |
| 17 | 17 | for _, r := range args[0] { | |
| @@ -11,7 +11,7 @@ var ErrInvalidArguments = errors.New("invalid command arguments") | |||||
| 11 | // ParsePositiveDecimal accepts exactly one base-10 positive decimal value. | 11 | // ParsePositiveDecimal accepts exactly one base-10 positive decimal value. | ||
| 12 | // It deliberately rejects signs, whitespace, zero, and non-canonical forms. | 12 | // It deliberately rejects signs, whitespace, zero, and non-canonical forms. | ||
| 13 | func ParsePositiveDecimal(args []string) (int, error) { | 13 | func ParsePositiveDecimal(args []string) (int, error) { | ||
| 14 | - | if len(args) != 1 || args[0] == "" { | 14 | + | if len(args) != 1 || args[0] == "" || (len(args[0]) > 1 && args[0][0] == '0') { |
| 15 | return 0, ErrInvalidArguments | 15 | return 0, ErrInvalidArguments | ||
| 16 | } | 16 | } | ||
| 17 | for _, r := range args[0] { | 17 | for _, r := range args[0] { | ||
M internal/usecase/command/command_test.go +6 -0
| @@ -13,6 +13,12 @@ func TestParsePositiveDecimal(t *testing.T) { | |||
| 13 | 13 | invalid bool | |
| 14 | 14 | }{ | |
| 15 | 15 | {"one", []string{"1"}, 1, false}, | |
| 16 | + | {"multi-digit", []string{"42"}, 42, false}, | |
| 17 | + | {"overflow", []string{"999999999999999999999999999999999999"}, 0, true}, | |
| 18 | + | {"leading zero", []string{"01"}, 0, true}, | |
| 19 | + | {"multiple leading zeros", []string{"0001"}, 0, true}, | |
| 20 | + | {"all zeros", []string{"00"}, 0, true}, | |
| 21 | + | {"leading zero on multi-digit value", []string{"010"}, 0, true}, | |
| 16 | 22 | {"zero", []string{"0"}, 0, true}, | |
| 17 | 23 | {"negative", []string{"-1"}, 0, true}, | |
| 18 | 24 | {"extra", []string{"1", "2"}, 0, true}, | |
| @@ -13,6 +13,12 @@ func TestParsePositiveDecimal(t *testing.T) { | |||||
| 13 | invalid bool | 13 | invalid bool | ||
| 14 | }{ | 14 | }{ | ||
| 15 | {"one", []string{"1"}, 1, false}, | 15 | {"one", []string{"1"}, 1, false}, | ||
| 16 | + | {"multi-digit", []string{"42"}, 42, false}, | |||
| 17 | + | {"overflow", []string{"999999999999999999999999999999999999"}, 0, true}, | |||
| 18 | + | {"leading zero", []string{"01"}, 0, true}, | |||
| 19 | + | {"multiple leading zeros", []string{"0001"}, 0, true}, | |||
| 20 | + | {"all zeros", []string{"00"}, 0, true}, | |||
| 21 | + | {"leading zero on multi-digit value", []string{"010"}, 0, true}, | |||
| 16 | {"zero", []string{"0"}, 0, true}, | 22 | {"zero", []string{"0"}, 0, true}, | ||
| 17 | {"negative", []string{"-1"}, 0, true}, | 23 | {"negative", []string{"-1"}, 0, true}, | ||
| 18 | {"extra", []string{"1", "2"}, 0, true}, | 24 | {"extra", []string{"1", "2"}, 0, true}, | ||