Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions orderlyid.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,15 @@ type Parsed struct {
func Parse(s string) (*Parsed, error) {
s = strings.TrimSpace(s)
base := s
csGiven := ""
hasChecksum := false
if i := strings.LastIndexByte(s, '-'); i >= 0 {
base = s[:i]
csGiven := s[i+1:]
csGiven = s[i+1:]
hasChecksum = true
if len(csGiven) != 4 {
return nil, fmt.Errorf("%w: must be 4 chars", ErrInvalidChecksum)
}
expected := checksum4Base(base)
if !strings.EqualFold(csGiven, expected) {
return nil, fmt.Errorf("%w: checksum mismatch", ErrInvalidChecksum)
}
}
i := strings.IndexByte(base, '_')
if i <= 0 {
Expand All @@ -232,6 +231,12 @@ func Parse(s string) (*Parsed, error) {
return nil, fmt.Errorf("%w: invalid character at pos %d", ErrInvalidBase32, j)
}
}
if hasChecksum {
expected := checksum4Base(base)
if !strings.EqualFold(csGiven, expected) {
return nil, fmt.Errorf("%w: checksum mismatch", ErrInvalidChecksum)
}
}
buf, err := b32decode(payload)
if err != nil {
return nil, err
Expand Down
31 changes: 31 additions & 0 deletions orderlyid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,37 @@ func TestParseErrorsSupportErrorsIs(t *testing.T) {
}
}

func TestParseInvalidChecksumBaseDoesNotPanic(t *testing.T) {
tests := []struct {
name string
id string
want error
}{
{name: "missing payload separator", id: "order-abcd", want: ErrInvalidFormat},
{name: "invalid prefix", id: "Order_00000000000000000000000000000000-abcd", want: ErrInvalidPrefix},
{name: "short payload", id: "order_123-abcd", want: ErrInvalidPayloadLength},
{name: "invalid base32", id: "order_0000000000000000000000000000000!-abcd", want: ErrInvalidBase32},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Fatalf("Parse panicked: %v", r)
}
}()

_, err := Parse(tt.id)
if err == nil {
t.Fatalf("expected error")
}
if !errors.Is(err, tt.want) {
t.Fatalf("expected %v, got %v", tt.want, err)
}
})
}
}

func TestNewFromPartsErrorsSupportErrorsIs(t *testing.T) {
if _, err := NewFromParts(Components{Prefix: "Bad!"}, false); err == nil {
t.Fatalf("expected invalid prefix error")
Expand Down
Loading