frame fuzzer: handle frames one by one (#3884)

This more closely matches what the connection does.
This commit is contained in:
Marten Seemann 2023-06-13 23:44:25 +03:00 committed by GitHub
parent c52b583561
commit 30527c58c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -36,28 +36,17 @@ func Fuzz(data []byte) int {
parser := wire.NewFrameParser(true) parser := wire.NewFrameParser(true)
parser.SetAckDelayExponent(protocol.DefaultAckDelayExponent) parser.SetAckDelayExponent(protocol.DefaultAckDelayExponent)
initialLen := len(data) var numFrames int
var b []byte
var frames []wire.Frame
for len(data) > 0 { for len(data) > 0 {
initialLen := len(data)
l, f, err := parser.ParseNext(data, encLevel, version) l, f, err := parser.ParseNext(data, encLevel, version)
if err != nil { if err != nil {
break break
} }
data = data[l:] data = data[l:]
frames = append(frames, f) numFrames++
}
parsedLen := initialLen - len(data)
if len(frames) == 0 {
return 0
}
var b []byte
for _, f := range frames {
if f == nil { // PADDING frame if f == nil { // PADDING frame
b = append(b, 0)
continue continue
} }
// We accept empty STREAM frames, but we don't write them. // We accept empty STREAM frames, but we don't write them.
@ -67,21 +56,27 @@ func Fuzz(data []byte) int {
continue continue
} }
} }
lenBefore := len(b)
b, err := f.Append(b, version) startLen := len(b)
parsedLen := initialLen - len(data)
b, err = f.Append(b, version)
if err != nil { if err != nil {
panic(fmt.Sprintf("Error writing frame %#v: %s", f, err)) panic(fmt.Sprintf("Error writing frame %#v: %s", f, err))
} }
frameLen := len(b) - lenBefore frameLen := protocol.ByteCount(len(b) - startLen)
if f.Length(version) != protocol.ByteCount(frameLen) { if f.Length(version) != frameLen {
panic(fmt.Sprintf("Inconsistent frame length for %#v: expected %d, got %d", f, frameLen, f.Length(version))) panic(fmt.Sprintf("Inconsistent frame length for %#v: expected %d, got %d", f, frameLen, f.Length(version)))
} }
if sf, ok := f.(*wire.StreamFrame); ok { if sf, ok := f.(*wire.StreamFrame); ok {
sf.PutBack() sf.PutBack()
} }
} if frameLen > protocol.ByteCount(parsedLen) {
if len(b) > parsedLen {
panic(fmt.Sprintf("Serialized length (%d) is longer than parsed length (%d)", len(b), parsedLen)) panic(fmt.Sprintf("Serialized length (%d) is longer than parsed length (%d)", len(b), parsedLen))
} }
}
if numFrames == 0 {
return 0
}
return 1 return 1
} }