f82653cb06
This allows gofuzz to store the mutating input as coverage if it reaches any new coverage, even if it didn't make it to the end of the test.
113 lines
2.9 KiB
Go
113 lines
2.9 KiB
Go
// +build gofuzz
|
|
|
|
package lnwirefuzz
|
|
|
|
import (
|
|
"bytes"
|
|
"reflect"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
// Fuzz_node_announcement is used by go-fuzz.
|
|
func Fuzz_node_announcement(data []byte) int {
|
|
// Prefix with MsgNodeAnnouncement.
|
|
data = prefixWithMsgType(data, lnwire.MsgNodeAnnouncement)
|
|
|
|
// Create an empty message so that the FuzzHarness func can check
|
|
// if the max payload constraint is violated.
|
|
emptyMsg := lnwire.NodeAnnouncement{}
|
|
|
|
// We have to do this here instead of in fuzz.Harness so that
|
|
// reflect.DeepEqual isn't called. Address (de)serialization messes up
|
|
// the fuzzing assertions.
|
|
|
|
// Create a reader with the byte array.
|
|
r := bytes.NewReader(data)
|
|
|
|
// Make sure byte array length (excluding 2 bytes for message type) is
|
|
// less than max payload size for the wire message. We check this because
|
|
// otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage
|
|
// due to a large message size.
|
|
payloadLen := uint32(len(data)) - 2
|
|
if payloadLen > emptyMsg.MaxPayloadLength(0) {
|
|
// Ignore this input - max payload constraint violated.
|
|
return 1
|
|
}
|
|
|
|
msg, err := lnwire.ReadMessage(r, 0)
|
|
if err != nil {
|
|
// go-fuzz generated []byte that cannot be represented as a
|
|
// wire message but we will return 0 so go-fuzz can modify the
|
|
// input.
|
|
return 1
|
|
}
|
|
|
|
// We will serialize the message into a new bytes buffer.
|
|
var b bytes.Buffer
|
|
if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil {
|
|
// Could not serialize message into bytes buffer, panic
|
|
panic(err)
|
|
}
|
|
|
|
// Deserialize the message from the serialized bytes buffer, and then
|
|
// assert that the original message is equal to the newly deserialized
|
|
// message.
|
|
newMsg, err := lnwire.ReadMessage(&b, 0)
|
|
if err != nil {
|
|
// Could not deserialize message from bytes buffer, panic
|
|
panic(err)
|
|
}
|
|
|
|
// Now compare every field instead of using reflect.DeepEqual for the
|
|
// Addresses field.
|
|
var shouldPanic bool
|
|
first := msg.(*lnwire.NodeAnnouncement)
|
|
second := newMsg.(*lnwire.NodeAnnouncement)
|
|
if !bytes.Equal(first.Signature[:], second.Signature[:]) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if !reflect.DeepEqual(first.Features, second.Features) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if first.Timestamp != second.Timestamp {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if !bytes.Equal(first.NodeID[:], second.NodeID[:]) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if !reflect.DeepEqual(first.RGBColor, second.RGBColor) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if !bytes.Equal(first.Alias[:], second.Alias[:]) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if len(first.Addresses) != len(second.Addresses) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
for i := range first.Addresses {
|
|
if first.Addresses[i].String() != second.Addresses[i].String() {
|
|
shouldPanic = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !reflect.DeepEqual(first.ExtraOpaqueData, second.ExtraOpaqueData) {
|
|
shouldPanic = true
|
|
}
|
|
|
|
if shouldPanic {
|
|
panic("original message and deserialized message are not equal")
|
|
}
|
|
|
|
// Add this input to the corpus.
|
|
return 1
|
|
}
|