1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
package fasthttp
import (
"bytes"
"net"
"testing"
)
// oracleValid replicates the original function's semantics using net.ParseIP:
// - Input must start with '['
// - There must be a closing ']' and a non-empty address between
// - Optional %zone allowed but must not be empty
// - Zone is stripped before checking with net.ParseIP
// - Must contain a ':' to be IPv6 (prevents raw IPv4-in-brackets).
func oracleValid(host []byte) bool {
if len(host) == 0 || host[0] != '[' {
// Original function: non-bracketed hosts return nil (treated as valid/no-op).
return true
}
end := bytes.IndexByte(host, ']')
if end < 0 {
return false
}
addr := host[1:end]
if len(addr) == 0 {
return false
}
// Split off %zone (if present).
if zi := bytes.IndexByte(addr, '%'); zi >= 0 {
// Zone must not be empty.
if zi == len(addr)-1 {
return false
}
addr = addr[:zi]
}
// Must contain ':' to be IPv6.
if bytes.IndexByte(addr, ':') < 0 {
return false
}
// Use net.ParseIP on the de-zoned address (this was the original check).
if ip := net.ParseIP(string(addr)); ip == nil {
return false
}
return true
}
func FuzzValidateIPv6Literal(f *testing.F) {
seeds := [][]byte{
[]byte(""), // non-bracketed => valid (no-op)
[]byte("example.com"), // non-bracketed => valid (no-op)
[]byte("["), // unterminated
[]byte("[]"), // empty
[]byte("[::]"),
[]byte("[::1]"),
[]byte("[2001:db8::1]"),
[]byte("[2001:db8::]"),
[]byte("[::ffff:192.168.0.1]"),
[]byte("[fe80::1%eth0]"),
[]byte("[fe80::1%]"), // empty zone
[]byte("[1234]"), // no colon
[]byte("[2001:db8:zzzz::1]"), // invalid hex
[]byte("[::ffff:256.0.0.1]"), // invalid v4 tail
[]byte("[2001:db8:::1]"), // triple colon
[]byte("[::1]:443"), // trailing port outside ']' is ignored by validator
[]byte("[2001:db8:0:0:0:0:2:1]"),
[]byte("[2001:db8:0:0:0:0:2:1%en0]"),
}
for _, s := range seeds {
f.Add(s)
}
f.Fuzz(func(t *testing.T, host []byte) {
gotErr := validateIPv6Literal(host)
wantValid := oracleValid(host)
if (gotErr == nil) != wantValid {
t.Fatalf("mismatch for %q: validateIPv6Literal err=%v, oracleValid=%v",
b2s(host), gotErr, wantValid)
}
})
}
|