1description("Canonicalization of IPv6 addresses."); 2 3cases = [ 4 ["[", ""], 5 ["[:", ""], 6 ["]", ""], 7 [":]", ""], 8 ["[]", ""], 9 ["[:]", ""], 10 11 // Regular IP address is invalid without bounding '[' and ']'. 12 ["2001:db8::1", ""], 13 ["[2001:db8::1", ""], 14 ["2001:db8::1]", ""], 15 16 // Regular IP addresses. 17 ["[::]", "[::]"], 18 ["[::1]", "[::1]"], 19 ["[1::]", "[1::]"], 20 ["[::192.168.0.1]", "[::c0a8:1]"], 21 ["[::ffff:192.168.0.1]", "[::ffff:c0a8:1]"], 22 23 // Leading zeros should be stripped. 24 ["[000:01:02:003:004:5:6:007]", "[0:1:2:3:4:5:6:7]"], 25 26 // Upper case letters should be lowercased. 27 ["[A:b:c:DE:fF:0:1:aC]", "[a:b:c:de:ff:0:1:ac]"], 28 29 // The same address can be written with different contractions, but should 30 // get canonicalized to the same thing. 31 ["[1:0:0:2::3:0]", "[1::2:0:0:3:0]"], 32 ["[1::2:0:0:3:0]", "[1::2:0:0:3:0]"], 33 34 // IPv4 addresses 35 // Only mapped and compat addresses can have IPv4 syntax embedded. 36 ["[::eeee:192.168.0.1]", ""], 37 ["[2001::192.168.0.1]", ""], 38 ["[1:2:192.168.0.1:5:6]", ""], 39 40 // IPv4 with last component missing. 41 ["[::ffff:192.1.2]", "[::ffff:c001:2]"], 42 43 // IPv4 using hex. 44 // FIXME: Should this format be disallowed? 45 ["[::ffff:0xC0.0Xa8.0x0.0x1]", "[::ffff:c0a8:1]"], 46 47 // There may be zeros surrounding the "::" contraction. 48 ["[0:0::0:0:8]", "[::8]"], 49 50 ["[2001:db8::1]", "[2001:db8::1]"], 51 52 // Can only have one "::" contraction in an IPv6 string literal. 53 ["[2001::db8::1]", ""], 54 55 // No more than 2 consecutive ':'s. 56 ["[2001:db8:::1]", ""], 57 ["[:::]", ""], 58 59 // Non-IP addresses due to invalid characters. 60 ["[2001::.com]", ""], 61 62 // Too many components means not an IP address. Similarly with too few if using IPv4 compat or mapped addresses. 63 ["[::192.168.0.0.1]", ""], 64 ["[::ffff:192.168.0.0.1]", ""], 65 ["[1:2:3:4:5:6:7:8:9]", ""], 66 67 // Too many bits (even though 8 comonents, the last one holds 32 bits). 68 ["[0:0:0:0:0:0:0:192.168.0.1]", ""], 69 70 // Too many bits specified -- the contraction would have to be zero-length 71 // to not exceed 128 bits. 72 ["[1:2:3:4:5:6::192.168.0.1]", ""], 73 74 // The contraction is for 16 bits of zero. 75 ["[1:2:3:4:5:6::8]", "[1:2:3:4:5:6:0:8]"], 76 77 // Cannot have a trailing colon. 78 ["[1:2:3:4:5:6:7:8:]", ""], 79 ["[1:2:3:4:5:6:192.168.0.1:]", ""], 80 81 // Cannot have negative numbers. 82 ["[-1:2:3:4:5:6:7:8]", ""], 83 84 // Scope ID -- the URL may contain an optional ["%" <scope_id>] section. 85 // The scope_id should be included in the canonicalized URL, and is an 86 // unsigned decimal number. 87 88 // Don't allow scope-id 89 ["[1::%1]", ""], 90 ["[1::%eth0]", ""], 91 ["[1::%]", ""], 92 ["[%]", ""], 93 ["[::%:]", ""], 94 95 // Don't allow leading or trailing colons. 96 ["[:0:0::0:0:8]", ""], 97 ["[0:0::0:0:8:]", ""], 98 ["[:0:0::0:0:8:]", ""], 99 100 // Two dots in a row means not an IP address. 101 ["[::192.168..1]", ""], 102 103 // Spaces should be rejected. 104 ["[::1 hello]", ""] 105]; 106 107// We test the empty string individually. 108shouldBe("canonicalize('http:///')", "'http:'"); 109 110for (var i = 0; i < cases.length; ++i) { 111 test_vector = cases[i][0]; 112 expected_result = cases[i][1]; 113 if (expected_result === "") { 114 // We use "" to represent that the test vector ought not to parse. 115 // It appears that we're supposed to apply a default canonicalization, 116 // and the escape function escapes too much! 117 expected_result = test_vector.toLowerCase(); 118 ['%', ' '].forEach(function(c){ 119 expected_result = expected_result.replace(c, escape(c)); 120 }) 121 } 122 shouldBe("canonicalize('http://" + test_vector + "/')", 123 "'http://" + expected_result + "/'"); 124} 125 126var successfullyParsed = true; 127