Add native UDP protobuf reference vectors

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-09 19:58:39 -04:00
committed by Brandon McGinty
parent d50c6726ad
commit 9678816a4c
2 changed files with 20 additions and 2 deletions
+1 -1
View File
@@ -168,7 +168,7 @@ Priority 2: protocol and data correctness
dereferencing and return errInvalidProtobuf for malformed server packets. dereferencing and return errInvalidProtobuf for malformed server packets.
Audit all packet pointer dereferences similarly. Audit all packet pointer dereferences similarly.
21. UDP protocol state has no complete interoperability test coverage [x] 21. UDP protocol state has no complete interoperability test coverage
Files: gumble/gumble/udp15.go, gumble/gumble/udp.go Files: gumble/gumble/udp15.go, gumble/gumble/udp.go
Tests are mostly local encrypt/decrypt round trips. Add captured/reference Tests are mostly local encrypt/decrypt round trips. Add captured/reference
vectors from current Mumble for CryptSetup, encrypted audio, ping, packet vectors from current Mumble for CryptSetup, encrypted audio, ping, packet
+19 -1
View File
@@ -212,6 +212,17 @@ func TestUDPAudioProtobuf(t *testing.T) {
} }
} }
// Reference wire vector from the MumbleUDP.Audio protobuf layout. This guards
// field numbers, standard-varint framing, terminators, and position encoding.
func TestUDPAudioProtobufReferenceVector(t *testing.T) {
x, y, z := float32(1), float32(2), float32(3)
got := encodeUDPAudio(2, 300, []byte{0xaa, 0xbb}, true, &x, &y, &z)
want := mustDecodeHex("080220ac022a02aabb320c0000803f0000004000004040800101")
if !bytes.Equal(got, want) {
t.Fatalf("wire vector = %x, want %x", got, want)
}
}
func TestUDPAudioProtobufIncomingFields(t *testing.T) { func TestUDPAudioProtobufIncomingFields(t *testing.T) {
var packet bytes.Buffer var packet bytes.Buffer
writeVarint := func(v uint64) { writeVarint := func(v uint64) {
@@ -228,6 +239,10 @@ func TestUDPAudioProtobufIncomingFields(t *testing.T) {
writeVarint(5<<3 | 2) // opus_data writeVarint(5<<3 | 2) // opus_data
writeVarint(2) writeVarint(2)
packet.Write([]byte{0xaa, 0xbb}) packet.Write([]byte{0xaa, 0xbb})
writeVarint(7<<3 | 5) // volume_adjustment fixed32
var volume [4]byte
binary.LittleEndian.PutUint32(volume[:], math.Float32bits(0.75))
packet.Write(volume[:])
writeVarint(6<<3 | 2) // packed positional_data writeVarint(6<<3 | 2) // packed positional_data
writeVarint(12) writeVarint(12)
for _, f := range []uint32{math.Float32bits(1), math.Float32bits(2), math.Float32bits(3)} { for _, f := range []uint32{math.Float32bits(1), math.Float32bits(2), math.Float32bits(3)} {
@@ -236,10 +251,13 @@ func TestUDPAudioProtobufIncomingFields(t *testing.T) {
packet.Write(buf[:]) packet.Write(buf[:])
} }
session, frame, opusData, terminator, context, position, _ := decodeUDPAudio(packet.Bytes()) session, frame, opusData, terminator, context, position, volumeAdjustment := decodeUDPAudio(packet.Bytes())
if session != 123 || frame != 1<<32 || !bytes.Equal(opusData, []byte{0xaa, 0xbb}) || terminator || context != 3 { if session != 123 || frame != 1<<32 || !bytes.Equal(opusData, []byte{0xaa, 0xbb}) || terminator || context != 3 {
t.Fatalf("decoded unexpected audio: session=%d frame=%d opus=%x terminator=%v context=%d", session, frame, opusData, terminator, context) t.Fatalf("decoded unexpected audio: session=%d frame=%d opus=%x terminator=%v context=%d", session, frame, opusData, terminator, context)
} }
if volumeAdjustment != 0.75 {
t.Fatalf("volume adjustment = %v", volumeAdjustment)
}
if position == nil || *position != [3]float32{1, 2, 3} { if position == nil || *position != [3]float32{1, 2, 3} {
t.Fatalf("position = %v, want [1 2 3]", position) t.Fatalf("position = %v, want [1 2 3]", position)
} }