diff --git a/pkg/database/compact_event.go b/pkg/database/compact_event.go index a277450..f5949f0 100644 --- a/pkg/database/compact_event.go +++ b/pkg/database/compact_event.go @@ -240,6 +240,11 @@ func readUint40(r io.Reader) (value uint64, err error) { // The resolver is used to look up pubkeys and event IDs from serials. // The eventId parameter is the full 32-byte event ID (from SerialEventId table). func UnmarshalCompactEvent(data []byte, eventId []byte, resolver SerialResolver) (ev *event.E, err error) { + // Validate eventId upfront to prevent returning events with zero IDs + if len(eventId) != 32 { + return nil, errors.New("invalid eventId: must be exactly 32 bytes") + } + r := bytes.NewReader(data) ev = new(event.E) diff --git a/pkg/database/fetch-event-by-serial.go b/pkg/database/fetch-event-by-serial.go index 65661eb..92561a9 100644 --- a/pkg/database/fetch-event-by-serial.go +++ b/pkg/database/fetch-event-by-serial.go @@ -44,9 +44,12 @@ func (d *D) FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error) { // Check if this is compact format if len(eventData) > 0 && eventData[0] == CompactFormatVersion { eventId, idErr := d.GetEventIdBySerial(ser) - if idErr == nil { - return UnmarshalCompactEvent(eventData, eventId, resolver) + if idErr != nil { + // Cannot decode compact format without event ID - return error + // DO NOT fall back to legacy unmarshal as compact format is not valid legacy format + return nil, fmt.Errorf("compact format inline but no event ID mapping for serial %d: %w", ser.Get(), idErr) } + return UnmarshalCompactEvent(eventData, eventId, resolver) } // Legacy binary format @@ -106,10 +109,14 @@ func (d *D) FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error) { // Check if this is compact format if len(v) > 0 && v[0] == CompactFormatVersion { eventId, idErr := d.GetEventIdBySerial(ser) - if idErr == nil { - ev, err = UnmarshalCompactEvent(v, eventId, resolver) + if idErr != nil { + // Cannot decode compact format without event ID - return error + // DO NOT fall back to legacy unmarshal as compact format is not valid legacy format + err = fmt.Errorf("compact format evt but no event ID mapping for serial %d: %w", ser.Get(), idErr) return } + ev, err = UnmarshalCompactEvent(v, eventId, resolver) + return } // Check if we have valid data before attempting to unmarshal diff --git a/pkg/database/fetch-events-by-serials.go b/pkg/database/fetch-events-by-serials.go index 515d2eb..963f6df 100644 --- a/pkg/database/fetch-events-by-serials.go +++ b/pkg/database/fetch-events-by-serials.go @@ -149,12 +149,10 @@ func (d *D) fetchSmallEvent(txn *badger.Txn, ser *types.Uint40) (ev *event.E, er resolver := NewDatabaseSerialResolver(d, d.serialCache) eventId, idErr := d.GetEventIdBySerial(ser) if idErr != nil { - // Fall back to legacy unmarshal - ev = new(event.E) - if err = ev.UnmarshalBinary(bytes.NewBuffer(eventData)); err != nil { - return nil, err - } - return ev, nil + // Cannot decode compact format without event ID - return error + // DO NOT fall back to legacy unmarshal as compact format is not valid legacy format + log.W.F("fetchSmallEvent: compact format but no event ID mapping for serial %d: %v", ser.Get(), idErr) + return nil, idErr } return UnmarshalCompactEvent(eventData, eventId, resolver) } @@ -196,12 +194,10 @@ func (d *D) fetchLegacyEvent(txn *badger.Txn, ser *types.Uint40) (ev *event.E, e resolver := NewDatabaseSerialResolver(d, d.serialCache) eventId, idErr := d.GetEventIdBySerial(ser) if idErr != nil { - // Fall back to legacy unmarshal - ev = new(event.E) - if err = ev.UnmarshalBinary(bytes.NewBuffer(v)); err != nil { - return nil, err - } - return ev, nil + // Cannot decode compact format without event ID - return error + // DO NOT fall back to legacy unmarshal as compact format is not valid legacy format + log.W.F("fetchLegacyEvent: compact format but no event ID mapping for serial %d: %v", ser.Get(), idErr) + return nil, idErr } return UnmarshalCompactEvent(v, eventId, resolver) } diff --git a/pkg/database/serial_cache.go b/pkg/database/serial_cache.go index 9b1553c..6764cf0 100644 --- a/pkg/database/serial_cache.go +++ b/pkg/database/serial_cache.go @@ -251,7 +251,11 @@ func (d *D) GetEventIdBySerial(ser *types.Uint40) (eventId []byte, err error) { } return item.Value(func(val []byte) error { - eventId = make([]byte, len(val)) + // Validate that the stored value is exactly 32 bytes + if len(val) != 32 { + return errors.New("corrupted event ID: expected 32 bytes") + } + eventId = make([]byte, 32) copy(eventId, val) return nil }) diff --git a/pkg/version/version b/pkg/version/version index 0131a13..1a765e8 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.47.0 +v0.47.1