fix and enhance stringToCm to parse LOC RR optional fields (#1148)
Automatically submitted.
This commit is contained in:
parent
81df27db17
commit
da812eed45
|
@ -415,6 +415,67 @@ func TestParseLOC(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this tests a subroutine for the LOC RR parser. It's complicated enough to test separately.
|
||||||
|
func TestStringToCm(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
// Test description: the input token and the expected return values from stringToCm.
|
||||||
|
token string
|
||||||
|
e uint8
|
||||||
|
m uint8
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{"100", 4, 1, true},
|
||||||
|
{"0100", 4, 1, true}, // leading 0 (allowed)
|
||||||
|
{"100.99", 4, 1, true},
|
||||||
|
{"90000000", 9, 9, true},
|
||||||
|
{"90000000.00", 9, 9, true},
|
||||||
|
{"0", 0, 0, true},
|
||||||
|
{"0.00", 0, 0, true},
|
||||||
|
{"0.01", 0, 1, true},
|
||||||
|
{".01", 0, 1, true}, // empty 'meter' part (allowed)
|
||||||
|
{"0.1", 1, 1, true},
|
||||||
|
|
||||||
|
// out of range (too large)
|
||||||
|
{"90000001", 0, 0, false},
|
||||||
|
{"90000000.01", 0, 0, false},
|
||||||
|
|
||||||
|
// more than 2 digits in 'cmeter' part
|
||||||
|
{"0.000", 0, 0, false},
|
||||||
|
{"0.001", 0, 0, false},
|
||||||
|
{"0.999", 0, 0, false},
|
||||||
|
// with plus or minus sign (disallowed)
|
||||||
|
{"-100", 0, 0, false},
|
||||||
|
{"+100", 0, 0, false},
|
||||||
|
{"0.-10", 0, 0, false},
|
||||||
|
{"0.+10", 0, 0, false},
|
||||||
|
{"0a.00", 0, 0, false}, // invalid string for 'meter' part
|
||||||
|
{".1x", 0, 0, false}, // invalid string for 'cmeter' part
|
||||||
|
{".", 0, 0, false}, // empty 'cmeter' part (disallowed)
|
||||||
|
{"1.", 0, 0, false}, // ditto
|
||||||
|
{"m", 0, 0, false}, // only the "m" suffix
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.token, func(t *testing.T) {
|
||||||
|
// In all cases the expected result is the same with or without the 'm' suffix.
|
||||||
|
// So we test both cases using the same test code.
|
||||||
|
for _, sfx := range []string{"", "m"} {
|
||||||
|
token := tc.token + sfx
|
||||||
|
e, m, ok := stringToCm(token)
|
||||||
|
if ok != tc.ok {
|
||||||
|
t.Fatal("unexpected validation result")
|
||||||
|
}
|
||||||
|
if m != tc.m {
|
||||||
|
t.Fatalf("Expected %d, got %d", tc.m, m)
|
||||||
|
}
|
||||||
|
if e != tc.e {
|
||||||
|
t.Fatalf("Expected %d, got %d", tc.e, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseDS(t *testing.T) {
|
func TestParseDS(t *testing.T) {
|
||||||
dt := map[string]string{
|
dt := map[string]string{
|
||||||
"example.net. 3600 IN DS 40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B 2071398F": "example.net.\t3600\tIN\tDS\t40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B2071398F",
|
"example.net. 3600 IN DS 40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B 2071398F": "example.net.\t3600\tIN\tDS\t40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B2071398F",
|
||||||
|
|
23
scan.go
23
scan.go
|
@ -1210,11 +1210,29 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
||||||
if cmeters, err = strconv.Atoi(s[1]); err != nil {
|
if cmeters, err = strconv.Atoi(s[1]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// There's no point in having more than 2 digits in this part, and would rather make the implementation complicated ('123' should be treated as '12').
|
||||||
|
// So we simply reject it.
|
||||||
|
// We also make sure the first character is a digit to reject '+-' signs.
|
||||||
|
if len(s[1]) > 2 || s[1][0] < '0' || s[1][0] > '9' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(s[1]) == 1 {
|
||||||
|
// 'nn.1' must be treated as 'nn-meters and 10cm, not 1cm.
|
||||||
|
cmeters *= 10
|
||||||
|
}
|
||||||
|
if len(s[0]) == 0 {
|
||||||
|
// This will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm).
|
||||||
|
break
|
||||||
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case 1:
|
case 1:
|
||||||
if meters, err = strconv.Atoi(s[0]); err != nil {
|
if meters, err = strconv.Atoi(s[0]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// RFC1876 states the max value is 90000000.00. The latter two conditions enforce it.
|
||||||
|
if s[0][0] < '0' || s[0][0] > '9' || meters > 90000000 || (meters == 90000000 && cmeters != 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
case 0:
|
case 0:
|
||||||
// huh?
|
// huh?
|
||||||
return 0, 0, false
|
return 0, 0, false
|
||||||
|
@ -1227,13 +1245,10 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
||||||
e = 0
|
e = 0
|
||||||
val = cmeters
|
val = cmeters
|
||||||
}
|
}
|
||||||
for val > 10 {
|
for val >= 10 {
|
||||||
e++
|
e++
|
||||||
val /= 10
|
val /= 10
|
||||||
}
|
}
|
||||||
if e > 9 {
|
|
||||||
ok = false
|
|
||||||
}
|
|
||||||
m = uint8(val)
|
m = uint8(val)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue