examples: fix IPv6 bounds check

This commit is contained in:
Anna Shaleva 2021-05-18 11:12:32 +03:00
parent 2eb91066ea
commit 2a9ce03376
2 changed files with 65 additions and 39 deletions

View file

@ -581,23 +581,47 @@ func checkIPv6(data string) bool {
if l < 3 || 8 < l {
return false
}
if fragments[0] == "2001" { // example addresses prefix
var hasEmpty bool
nums := make([]int, 8)
for i, f := range fragments {
if len(f) == 0 {
if i == 0 {
nums[i] = 0
} else if i == l-1 {
nums[7] = 0
} else if hasEmpty {
return false
} else {
hasEmpty = true
endIndex := 9 - l + i
for j := i; j < endIndex; j++ {
nums[j] = 0
}
}
} else {
if len(f) > 4 {
return false
}
n := std.Atoi(f, 16)
if 65535 < n {
panic("fragment overflows uint16: " + f)
}
idx := i
if hasEmpty {
idx = i + 8 - l
}
nums[idx] = n
}
}
f0 := nums[0]
if f0 < 0x2000 || f0 == 0x2002 || f0 == 0x3ffe || f0 > 0x3fff { // IPv6 Global Unicast https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
return false
}
var hasEmpty bool
for i := 1; i < l; i++ {
f := fragments[i]
fLen := len(f)
if fLen == 0 {
if i < l-1 && hasEmpty {
return false
}
hasEmpty = true
} else {
if fLen > 4 {
return false
}
_ = std.Atoi(f, 16) // check it won't panic
if f0 == 0x2001 {
f1 := nums[1]
if f1 < 0x200 || f1 == 0xdb8 {
return false
}
}
return true

View file

@ -197,7 +197,7 @@ func TestSetGetRecord(t *testing.T) {
testNameServiceInvoke(t, bc, nsHash, "getRecord", "1.2.3.4", "neo.com", int64(nns.A))
testNameServiceInvoke(t, bc, nsHash, "setRecord", stackitem.Null{}, "neo.com", int64(nns.A), "1.2.3.4")
testNameServiceInvoke(t, bc, nsHash, "getRecord", "1.2.3.4", "neo.com", int64(nns.A))
testNameServiceInvoke(t, bc, nsHash, "setRecord", stackitem.Null{}, "neo.com", int64(nns.AAAA), "2002:0000:1f1f:0000:0000:0100:11a0:addf")
testNameServiceInvoke(t, bc, nsHash, "setRecord", stackitem.Null{}, "neo.com", int64(nns.AAAA), "2001:0201:1f1f:0000:0000:0100:11a0:11df")
testNameServiceInvoke(t, bc, nsHash, "setRecord", stackitem.Null{}, "neo.com", int64(nns.CNAME), "nspcc.ru")
testNameServiceInvoke(t, bc, nsHash, "setRecord", stackitem.Null{}, "neo.com", int64(nns.TXT), "sometext")
@ -238,30 +238,32 @@ func TestSetGetRecord(t *testing.T) {
{Type: nns.A, Name: "1.1", ShouldFail: true},
{Type: nns.A, Name: "257", ShouldFail: true},
{Type: nns.A, Name: "1", ShouldFail: true},
{Type: nns.AAAA, Name: "2001:db8::8:800:200c:417a", ShouldFail: true},
{Type: nns.AAAA, Name: "ff01:db8::8:800:200c:417a"},
{Type: nns.AAAA, Name: "ff01::101"},
{Type: nns.AAAA, Name: "::1"},
{Type: nns.AAAA, Name: "::"},
{Type: nns.AAAA, Name: "2001:db8:0:0:8:800:200c:417a", ShouldFail: true},
{Type: nns.AAAA, Name: "ff01:db8:0:0:8:800:200c:417a"},
{Type: nns.AAAA, Name: "ff01:0:0:0:0:0:0:101"},
{Type: nns.AAAA, Name: "2001:0:0:0:0:0:0:101", ShouldFail: true},
{Type: nns.AAAA, Name: "ff01:0:0:0:0:0:0:101"},
{Type: nns.AAAA, Name: "0:0:0:0:0:0:0:1"},
{Type: nns.AAAA, Name: "2001:0:0:0:0:0:0:1", ShouldFail: true},
{Type: nns.AAAA, Name: "0:0:0:0:0:0:0:0"},
{Type: nns.AAAA, Name: "2001:0:0:0:0:0:0:0", ShouldFail: true},
{Type: nns.AAAA, Name: "2001:DB8::8:800:200C:417A", ShouldFail: true},
{Type: nns.AAAA, Name: "FF01:DB8::8:800:200C:417A"},
{Type: nns.AAAA, Name: "FF01::101"},
{Type: nns.AAAA, Name: "fF01::101"},
{Type: nns.AAAA, Name: "2001:DB8:0:0:8:800:200C:417A", ShouldFail: true},
{Type: nns.AAAA, Name: "FF01:DB8:0:0:8:800:200C:417A"},
{Type: nns.AAAA, Name: "FF01:0:0:0:0:0:0:101"},
{Type: nns.AAAA, Name: "::ffff:1.01.1.01", ShouldFail: true},
// {2000} & {2001} & ]2002, 3ffe[ & {3fff} are valid values for IPv6 fragment0
{Type: nns.AAAA, Name: "2002:db8::8:800:200c:417a", ShouldFail: true},
{Type: nns.AAAA, Name: "3ffd:1b8::8:800:200c:417a"},
{Type: nns.AAAA, Name: "3ffd::101"},
{Type: nns.AAAA, Name: "2003::1"},
{Type: nns.AAAA, Name: "2003::"},
{Type: nns.AAAA, Name: "2002:db8:0:0:8:800:200c:417a", ShouldFail: true},
{Type: nns.AAAA, Name: "3ffd:db8:0:0:8:800:200c:417a"},
{Type: nns.AAAA, Name: "3ffd:0:0:0:0:0:0:101"},
{Type: nns.AAAA, Name: "2002:0:0:0:0:0:0:101", ShouldFail: true},
{Type: nns.AAAA, Name: "3ffd:0:0:0:0:0:0:101"},
{Type: nns.AAAA, Name: "2001:200:0:0:0:0:0:1"},
{Type: nns.AAAA, Name: "0:0:0:0:0:0:0:1", ShouldFail: true},
{Type: nns.AAAA, Name: "2002:0:0:0:0:0:0:1", ShouldFail: true},
{Type: nns.AAAA, Name: "2001:200:0:0:0:0:0:0"},
{Type: nns.AAAA, Name: "2002:0:0:0:0:0:0:0", ShouldFail: true},
{Type: nns.AAAA, Name: "2002:DB8::8:800:200C:417A", ShouldFail: true},
{Type: nns.AAAA, Name: "3FFD:1B8::8:800:200C:417A"},
{Type: nns.AAAA, Name: "3FFD::101"},
{Type: nns.AAAA, Name: "3fFD::101"},
{Type: nns.AAAA, Name: "2002:DB8:0:0:8:800:200C:417A", ShouldFail: true},
{Type: nns.AAAA, Name: "3FFD:DB8:0:0:8:800:200C:417A"},
{Type: nns.AAAA, Name: "3FFD:0:0:0:0:0:0:101"},
{Type: nns.AAAA, Name: "3FFD::ffff:1.01.1.01", ShouldFail: true},
{Type: nns.AAAA, Name: "2001:DB8:0:0:8:800:200C:4Z", ShouldFail: true},
{Type: nns.AAAA, Name: "::13.1.68.3", ShouldFail: true},
{Type: nns.AAAA, Name: "2001::13.1.68.3", ShouldFail: true},
}
for _, testCase := range testCases {
var expected interface{}