mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-03-18 05:42:20 +01:00
fix binary encoding stupid encoding bug that just guessed a slice length and if we were to go above it it would just panic.
for example: https://github.com/bitvora/wot-relay/issues/16
This commit is contained in:
parent
e175e634c8
commit
7787a4fcf7
@ -1,13 +1,16 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/test_common"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBinaryPartialGet(t *testing.T) {
|
||||
@ -40,22 +43,44 @@ func TestBinaryPartialGet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBinaryEncodeBackwardsCompatible(t *testing.T) {
|
||||
for i, jevt := range test_common.NormalEvents {
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
b64bevt := test_common.BinaryEventsBase64[i]
|
||||
bevt, err := base64.StdEncoding.DecodeString(b64bevt)
|
||||
require.NoError(t, err)
|
||||
|
||||
pevt := &nostr.Event{}
|
||||
err = json.Unmarshal([]byte(jevt), pevt)
|
||||
require.NoError(t, err)
|
||||
|
||||
encoded, err := Marshal(pevt)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, bevt, encoded)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBinaryEncode(t *testing.T) {
|
||||
for _, jevt := range test_common.NormalEvents {
|
||||
pevt := &nostr.Event{}
|
||||
if err := json.Unmarshal([]byte(jevt), pevt); err != nil {
|
||||
t.Fatalf("failed to decode normal json: %s", err)
|
||||
}
|
||||
bevt, err := Marshal(pevt)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to encode binary: %s", err)
|
||||
}
|
||||
evt := &nostr.Event{}
|
||||
if err := Unmarshal(bevt, evt); err != nil {
|
||||
t.Fatalf("error unmarshalling binary: %s", err)
|
||||
}
|
||||
checkParsedCorrectly(t, pevt, jevt)
|
||||
checkParsedCorrectly(t, evt, jevt)
|
||||
for i, jevt := range test_common.NormalEvents {
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
pevt := &nostr.Event{}
|
||||
if err := json.Unmarshal([]byte(jevt), pevt); err != nil {
|
||||
t.Fatalf("failed to decode normal json: %s", err)
|
||||
}
|
||||
bevt, err := Marshal(pevt)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to encode binary: %s", err)
|
||||
}
|
||||
evt := &nostr.Event{}
|
||||
if err := Unmarshal(bevt, evt); err != nil {
|
||||
t.Fatalf("error unmarshalling binary: %s", err)
|
||||
}
|
||||
|
||||
checkParsedCorrectly(t, pevt, jevt)
|
||||
checkParsedCorrectly(t, evt, jevt)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
0
binary/binaryevents.base64
Normal file
0
binary/binaryevents.base64
Normal file
@ -74,35 +74,30 @@ func Marshal(evt *nostr.Event) ([]byte, error) {
|
||||
}
|
||||
copy(buf[136:], content)
|
||||
|
||||
curr := 136 + len(content)
|
||||
|
||||
if tagCount := len(evt.Tags); tagCount > MaxTagCount {
|
||||
return nil, fmt.Errorf("can't encode too many tags: %d, max is %d", tagCount, MaxTagCount)
|
||||
} else {
|
||||
binary.BigEndian.PutUint16(buf[curr:curr+2], uint16(tagCount))
|
||||
binary.BigEndian.PutUint16(buf[136+len(content):136+len(content)+2], uint16(tagCount))
|
||||
}
|
||||
curr++
|
||||
|
||||
buf = buf[0 : 136+len(content)+2]
|
||||
|
||||
for _, tag := range evt.Tags {
|
||||
curr++
|
||||
if itemCount := len(tag); itemCount > MaxTagItemCount {
|
||||
return nil, fmt.Errorf("can't encode a tag with so many items: %d, max is %d", itemCount, MaxTagItemCount)
|
||||
} else {
|
||||
buf[curr] = uint8(itemCount)
|
||||
buf = append(buf, uint8(itemCount))
|
||||
}
|
||||
for _, item := range tag {
|
||||
curr++
|
||||
itemb := []byte(item)
|
||||
itemSize := len(itemb)
|
||||
if itemSize > MaxTagItemSize {
|
||||
return nil, fmt.Errorf("tag item is too large: %d, max is %d", itemSize, MaxTagItemSize)
|
||||
}
|
||||
binary.BigEndian.PutUint16(buf[curr:curr+2], uint16(itemSize))
|
||||
itemEnd := curr + 2 + itemSize
|
||||
copy(buf[curr+2:itemEnd], itemb)
|
||||
curr = itemEnd
|
||||
buf = binary.BigEndian.AppendUint16(buf, uint16(itemSize))
|
||||
buf = append(buf, itemb...)
|
||||
buf = append(buf, 0)
|
||||
}
|
||||
}
|
||||
buf = buf[0 : curr+1]
|
||||
return buf, nil
|
||||
}
|
||||
|
42
test_common/binaryevents_base64.go
Normal file
42
test_common/binaryevents_base64.go
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user