diff --git a/id.go b/id.go index e13ad15..90b7d56 100644 --- a/id.go +++ b/id.go @@ -288,8 +288,8 @@ func (id *ID) UnmarshalJSON(b []byte) error { *id = nilID return nil } - // Check the slice length to prevent panic on passing it to UnmarshalText() - if len(b) < 2 { + // Only JSON strings can contain an encoded ID. + if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { return ErrInvalidID } return id.UnmarshalText(b[1 : len(b)-1]) diff --git a/id_test.go b/id_test.go index a88522a..2298068 100644 --- a/id_test.go +++ b/id_test.go @@ -510,7 +510,6 @@ func TestID_IsZero(t *testing.T) { } } - func TestNilID(t *testing.T) { got := ID{} if want := NilID(); !reflect.DeepEqual(got, want) { @@ -622,3 +621,24 @@ func TestSort(t *testing.T) { t.Fail() } } + +func TestIDJSONRejectsNonStringValues(t *testing.T) { + for _, input := range []string{ + `1111111111111111111101`, + `[11111111111111111110]`, + } { + t.Run(input, func(t *testing.T) { + if !json.Valid([]byte(input)) { + t.Fatal("test input must be valid JSON") + } + original := IDs[0].id + got := original + if err := json.Unmarshal([]byte(input), &got); err != ErrInvalidID { + t.Errorf("got error %v, want %v", err, ErrInvalidID) + } + if got != original { + t.Errorf("invalid JSON type changed ID: got %v, want %v", got, original) + } + }) + } +}