allow non-hex e and p tags

mostly because some clients use p tags in follow lists for whatever reason. follow lists are generally fetched by pubkey+kind so the missing index because it's not a pubkey is really nbd, and pubkey tag searches will also work with the kind.
This commit is contained in:
2025-06-10 22:10:33 +01:00
parent faf3ebfdba
commit 789c7913e7
6 changed files with 37 additions and 19 deletions

View File

@@ -63,7 +63,7 @@ func (d *D) GetWordsFromContent(ev *event.E) (wordMap map[string]int) {
!IsEntity(w) && !IsEntity(w) &&
!bytes.Contains(w, []byte(".")) { !bytes.Contains(w, []byte(".")) {
if len(w) == 64 || len(w) == 128 { if len(w) == 64 || len(w) == 128 {
if _, err := hex.Dec(string(w)); !chk.E(err) { if _, err := hex.Dec(string(w)); err == nil {
continue continue
} }
} }

View File

@@ -164,6 +164,9 @@ func (d *D) GetEventIndexes(ev *event.E) (indices [][]byte, ser *varint.V, err e
continue continue
} }
ph := pubhash.New() ph := pubhash.New()
if len(pkb) == 0 {
continue
}
if err = ph.FromPubkey(pkb); chk.E(err) { if err = ph.FromPubkey(pkb); chk.E(err) {
err = nil err = nil
continue continue

View File

@@ -88,7 +88,7 @@ func TestGetEventIndexes(t *testing.T) {
// check the event encodes to binary, decodes, and produces the identical canonical form // check the event encodes to binary, decodes, and produces the identical canonical form
binE := new(bytes.Buffer) binE := new(bytes.Buffer)
if err = ev.MarshalWrite(binE); chk.E(err) { if err = ev.MarshalWrite(binE); chk.E(err) {
// log.I.F("bogus tags probably: %s", b) log.I.F("bogus tags probably: %s", b)
encErrs++ encErrs++
// events that marshal with errors have e and p tag values that aren't hex and should not be accepted // events that marshal with errors have e and p tag values that aren't hex and should not be accepted
continue continue

View File

@@ -50,7 +50,7 @@ func TestD_StoreEvent(t *testing.T) {
count++ count++
if count%1000 == 0 { if count%1000 == 0 {
log.I.F("unmarshaled %d events", count) log.I.F("unmarshaled %d events", count)
break // break
} }
if err = d.StoreEvent(ev); chk.E(err) { if err = d.StoreEvent(ev); chk.E(err) {
continue continue

View File

@@ -5,7 +5,6 @@ import (
"x.realy.lol/chk" "x.realy.lol/chk"
"x.realy.lol/ec/schnorr" "x.realy.lol/ec/schnorr"
"x.realy.lol/errorf"
"x.realy.lol/hex" "x.realy.lol/hex"
"x.realy.lol/timestamp" "x.realy.lol/timestamp"
"x.realy.lol/varint" "x.realy.lol/varint"
@@ -49,14 +48,20 @@ func (ev *E) MarshalWrite(w io.Writer) (err error) {
for i, y := range x { for i, y := range x {
if i == 1 && isBin { if i == 1 && isBin {
var b []byte var b []byte
b, err = hex.Dec(y) if b, err = hex.Dec(y); err != nil {
if err != nil { b = []byte(y)
err = errorf.E("e or p tag value not hex: %s", err.Error()) // non-hex "p" or "e" tags have a 1 prefix to indicate not to hex decode.
return _, _ = w.Write([]byte{1})
} err = nil
} else {
if len(b) != 32 { if len(b) != 32 {
err = errorf.E("e or p tag value with invalid decoded byte length %d", len(b)) // err = errorf.E("e or p tag value with invalid decoded byte length %d '%0x'", len(b), b)
return b = []byte(y)
_, _ = w.Write([]byte{1})
} else {
// hex values have a 2 prefix
_, _ = w.Write([]byte{2})
}
} }
varint.Encode(w, uint64(len(b))) varint.Encode(w, uint64(len(b)))
_, _ = w.Write(b) _, _ = w.Write(b)
@@ -111,6 +116,14 @@ func (ev *E) UnmarshalRead(r io.Reader) (err error) {
var t []string var t []string
var isBin bool var isBin bool
for i := range nField { for i := range nField {
var pr byte
if i == 1 && isBin {
prf := make([]byte, 1)
if _, err = r.Read(prf); chk.E(err) {
return
}
pr = prf[0]
}
var lenField uint64 var lenField uint64
if lenField, err = varint.Decode(r); chk.E(err) { if lenField, err = varint.Decode(r); chk.E(err) {
return return
@@ -119,17 +132,19 @@ func (ev *E) UnmarshalRead(r io.Reader) (err error) {
if _, err = r.Read(field); chk.E(err) { if _, err = r.Read(field); chk.E(err) {
return return
} }
// if it is first field, length 1 and is e or p, the value field must be binary // if it is first field, length 1 and is e or p, the value field should be binary
if i == 0 && len(field) == 1 && (field[0] == 'e' || field[0] == 'p') { if i == 0 && len(field) == 1 && (field[0] == 'e' || field[0] == 'p') {
isBin = true isBin = true
} }
if i == 1 && isBin { if i == 1 && isBin {
// this is a binary value, was an e or p tag key, 32 bytes long, encode value if pr == 2 {
// field to hex // this is a binary value, was an e or p tag key, 32 bytes long, encode
// value field to hex
f := make([]byte, 64) f := make([]byte, 64)
_ = hex.EncBytes(f, field) _ = hex.EncBytes(f, field)
field = f field = f
} }
}
t = append(t, string(field)) t = append(t, string(field))
} }
ev.Tags = append(ev.Tags, t) ev.Tags = append(ev.Tags, t)

View File

@@ -261,7 +261,7 @@ func (tags Tags) Get_a_Tags() (atags []Tag_a) {
} }
// next must be a pubkey // next must be a pubkey
var pk []byte var pk []byte
if pk, err = hex.Dec(parts[1]); chk.E(err) { if pk, err = hex.Dec(parts[1]); err != nil {
continue continue
} }
atag.Pubkey = pk atag.Pubkey = pk