diff --git a/eventstream.go b/eventstream.go index 16c7f2e..ee8ae80 100644 --- a/eventstream.go +++ b/eventstream.go @@ -6,6 +6,7 @@ import ( "encoding/binary" "fmt" "io" + "unicode/utf8" ) // Event is a typed message published to the event stream. @@ -58,5 +59,9 @@ func ReadEvent(r io.Reader) (*Event, error) { return nil, err } + if !utf8.Valid(topic) { + return nil, fmt.Errorf("topic contains invalid UTF-8") + } + return &Event{Topic: string(topic), Payload: payload}, nil } diff --git a/zz_event_wire_test.go b/zz_event_wire_test.go index 934b6ab..dc919d2 100644 --- a/zz_event_wire_test.go +++ b/zz_event_wire_test.go @@ -143,3 +143,19 @@ func TestEventPayloadTooLarge(t *testing.T) { t.Fatal("expected error for oversized payload, got nil") } } + +func TestEventTopicInvalidUTF8(t *testing.T) { + t.Parallel() + var buf bytes.Buffer + // Craft topic with invalid UTF-8: byte 0xFF is never valid + invalidTopic := []byte{0x48, 0xFF, 0x69} // H + invalid + i + binary.Write(&buf, binary.BigEndian, uint16(len(invalidTopic))) + buf.Write(invalidTopic) + // Valid payload + binary.Write(&buf, binary.BigEndian, uint32(0)) + + _, err := eventstream.ReadEvent(&buf) + if err == nil { + t.Fatal("expected error for invalid UTF-8 topic, got nil") + } +}