- internal/{address,identity,protocol,tce,transport,verify} -> pkg/ so
external Go projects can import the verified core; invariant tests
updated for the new paths
- Config.TrustProxy: key rate limiting by X-Forwarded-For when the relay
sits behind a reverse proxy (off by default, header never trusted
otherwise)
- examples/service + examples/approve: complete passwordless login round
trip (mint request -> wallet approves -> local verify), run live in CI
- docs/SERVICE-GUIDE.md: the integration recipe
107 lines
3.3 KiB
Go
107 lines
3.3 KiB
Go
package tce
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// FuzzUvarint asserts totality and canonicality of the uvarint primitive:
|
|
// arbitrary bytes never panic, and any successful decode is minimal.
|
|
//
|
|
// A successful decode necessarily consumed the canonical encoding of its
|
|
// value, because the decoder rejects non-minimal forms. Re-encoding the value
|
|
// must therefore reproduce the consumed bytes exactly; if it did not, the
|
|
// grammar would be ambiguous and the encoding malleable.
|
|
func FuzzUvarint(f *testing.F) {
|
|
f.Add([]byte(nil))
|
|
f.Add([]byte{0x00})
|
|
f.Add([]byte{0x81, 0x00})
|
|
f.Add([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01})
|
|
f.Add(append(AppendUvarint(nil, 1<<40), 0x00)) // success then a trailing byte
|
|
|
|
f.Fuzz(func(t *testing.T, b []byte) {
|
|
d := NewDecoder(b)
|
|
v, err := d.Uvarint()
|
|
if err != nil {
|
|
return
|
|
}
|
|
consumed := b[:d.Offset()]
|
|
canon := AppendUvarint(nil, v)
|
|
if !bytes.Equal(consumed, canon) {
|
|
t.Fatalf("accepted non-canonical uvarint %x for value %d", consumed, v)
|
|
}
|
|
})
|
|
}
|
|
|
|
// FuzzDecodePrimitives asserts that the value and map decoders are total over
|
|
// arbitrary bytes: they never panic, never hang, and an accepted map is
|
|
// exactly reproducible by the encoder.
|
|
func FuzzDecodePrimitives(f *testing.F) {
|
|
f.Add([]byte(nil))
|
|
f.Add([]byte{0x01, 0x01, 'a', 0x02})
|
|
f.Add([]byte{0x02, 0x01, 'b', 0x02, 0x01, 'a', 0x01})
|
|
f.Add([]byte{0x00})
|
|
f.Add([]byte{0x04, 0x01, '0'})
|
|
f.Add([]byte{0x04, 0x03, '1', '.', '0'})
|
|
f.Add([]byte{0x02, 0x01, 'a', 0x02, 0x01, 'b', 0x02, 0x01, 'c', 0x01})
|
|
f.Add([]byte{0x04, 0x0c, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4'})
|
|
f.Add([]byte{0x01, 0x05, 0xe4, 0xbd, 0xa0, 0xe5, 0xa5, 0xbd}) // UTF-8 "你好"
|
|
|
|
f.Fuzz(func(t *testing.T, b []byte) {
|
|
d := NewDecoder(b)
|
|
m, err := d.Map(0)
|
|
if err != nil {
|
|
return
|
|
}
|
|
e := NewEncoder()
|
|
e.Map("claims", m, 0)
|
|
out, err := e.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("encoder rejected the decoder's own output: %v", err)
|
|
}
|
|
if !bytes.Equal(b[:d.Offset()], out) {
|
|
t.Fatalf("encode(decode(b)) != b:\n%x\n%x", b[:d.Offset()], out)
|
|
}
|
|
})
|
|
}
|
|
|
|
// FuzzStringValidation asserts the string validator never panics and agrees
|
|
// with itself on arbitrary byte strings.
|
|
func FuzzStringValidation(f *testing.F) {
|
|
f.Add("")
|
|
f.Add("valid")
|
|
f.Add("\xff\xfe")
|
|
f.Add("\x00")
|
|
// Long string: its length prefix is a multi-byte uvarint, the case that
|
|
// originally exposed the single-byte-prefix assumption in the decoder.
|
|
f.Add(strings.Repeat("a", 200))
|
|
f.Add("héllo, 世界")
|
|
|
|
f.Fuzz(func(t *testing.T, s string) {
|
|
if err := ValidateString(s, MaxStringValue); err != nil {
|
|
return
|
|
}
|
|
// An accepted string must be reproducible: encoding it and decoding
|
|
// the length prefix must yield the same bytes back. The prefix is a
|
|
// uvarint, so it may be more than one byte for long strings.
|
|
e := NewEncoder()
|
|
e.String("s", s, MaxStringValue)
|
|
out, err := e.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("encode rejected a string ValidateString accepted: %v", err)
|
|
}
|
|
d2 := NewDecoder(out)
|
|
n, perr := d2.Uvarint()
|
|
if perr != nil {
|
|
t.Fatalf("decoding the length prefix: %v", perr)
|
|
}
|
|
if n != uint64(len(s)) {
|
|
t.Fatalf("length prefix %d != %d", n, len(s))
|
|
}
|
|
chunk := out[d2.Offset():]
|
|
if string(chunk) != s {
|
|
t.Fatalf("string altered in encoding")
|
|
}
|
|
})
|
|
}
|