diff --git a/logtail/id.go b/logtail/id.go index 62762f78a..5460ce024 100644 --- a/logtail/id.go +++ b/logtail/id.go @@ -121,14 +121,17 @@ func (id PublicID) MarshalText() ([]byte, error) { } func (id *PublicID) UnmarshalText(s []byte) error { - b, err := hex.DecodeString(string(s)) - if err != nil { - return fmt.Errorf("logtail.PublicID.UnmarshalText: %v", err) + if len(s) != len(id)*2 { + return fmt.Errorf("logtail.PublicID.UnmarshalText: invalid hex length: %d", len(s)) } - if len(b) != len(id) { - return fmt.Errorf("logtail.PublicID.UnmarshalText: invalid hex length: %d", len(b)) + for i := range id { + a, ok1 := fromHexChar(s[i*2+0]) + b, ok2 := fromHexChar(s[i*2+1]) + if !ok1 || !ok2 { + return errors.New("invalid hex character") + } + id[i] = (a << 4) | b } - copy(id[:], b) return nil } diff --git a/logtail/logtail_test.go b/logtail/logtail_test.go index b4ba8f0e0..57f6f90aa 100644 --- a/logtail/logtail_test.go +++ b/logtail/logtail_test.go @@ -303,3 +303,26 @@ func TestParseAndRemoveLogLevel(t *testing.T) { } } } + +func TestPublicIDUnmarshalText(t *testing.T) { + const hexStr = "6c60a9e0e7af57170bb1347b2d477e4cbc27d4571a4923b21651456f931e3d55" + x := []byte(hexStr) + + var id PublicID + if err := id.UnmarshalText(x); err != nil { + t.Fatal(err) + } + if id.String() != hexStr { + t.Errorf("String = %q; want %q", id.String(), hexStr) + } + + n := int(testing.AllocsPerRun(1000, func() { + var id PublicID + if err := id.UnmarshalText(x); err != nil { + t.Fatal(err) + } + })) + if n != 0 { + t.Errorf("allocs = %v; want 0", n) + } +}