From b837dcb5f0de1f34f38937896ebab24d3e6711f7 Mon Sep 17 00:00:00 2001 From: woikos Date: Mon, 29 Dec 2025 13:39:49 +0100 Subject: [PATCH] Fix UTF-8 encoding error in compact event tag marshaling (v0.44.1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix binary pubkey/event ID values not being detected by tag.Marshal - Compact event decoder now returns 33-byte values with null terminator - This allows tag.Marshal to detect and hex-encode binary values correctly - Fixes "Could not decode a text frame as UTF-8" WebSocket errors Files modified: - pkg/database/compact_event.go: Return 33-byte binary with null terminator 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- pkg/database/compact_event.go | 24 ++++++++++++++++-------- pkg/version/version | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/pkg/database/compact_event.go b/pkg/database/compact_event.go index 32e70a3..a277450 100644 --- a/pkg/database/compact_event.go +++ b/pkg/database/compact_event.go @@ -355,7 +355,7 @@ func decodeTagElement(r io.Reader, resolver SerialResolver) (elem []byte, err er return elem, nil case TagElementPubkeySerial: - // Pubkey serial: 5 bytes -> lookup full pubkey -> return as 32-byte binary + // Pubkey serial: 5 bytes -> lookup full pubkey -> return as 33-byte binary serial, err := readUint40(r) if err != nil { return nil, err @@ -364,11 +364,14 @@ func decodeTagElement(r io.Reader, resolver SerialResolver) (elem []byte, err er if err != nil { return nil, err } - // Return as 32-byte binary (nostr library optimized format) - return pubkey, nil + // Return as 33-byte binary (32 bytes + null terminator) for tag.Marshal detection + result := make([]byte, 33) + copy(result, pubkey) + result[32] = 0 // null terminator + return result, nil case TagElementEventSerial: - // Event serial: 5 bytes -> lookup full event ID -> return as 32-byte binary + // Event serial: 5 bytes -> lookup full event ID -> return as 33-byte binary serial, err := readUint40(r) if err != nil { return nil, err @@ -377,15 +380,20 @@ func decodeTagElement(r io.Reader, resolver SerialResolver) (elem []byte, err er if err != nil { return nil, err } - // Return as 32-byte binary - return eventId, nil + // Return as 33-byte binary (32 bytes + null terminator) for tag.Marshal detection + result := make([]byte, 33) + copy(result, eventId) + result[32] = 0 // null terminator + return result, nil case TagElementEventIdFull: // Full event ID: 32 bytes (for unknown/forward references) - elem = make([]byte, 32) - if _, err = io.ReadFull(r, elem); err != nil { + // Return as 33-byte binary (32 bytes + null terminator) for tag.Marshal detection + elem = make([]byte, 33) + if _, err = io.ReadFull(r, elem[:32]); err != nil { return nil, err } + elem[32] = 0 // null terminator return elem, nil default: diff --git a/pkg/version/version b/pkg/version/version index 9052dab..f79cde7 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.44.0 +v0.44.1