Index: trunk/phase3/tests/phpunit/includes/IPTest.php |
— | — | @@ -39,17 +39,20 @@ |
40 | 40 | $this->assertFalse( IP::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); |
41 | 41 | $this->assertFalse( IP::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' ); |
42 | 42 | $this->assertFalse( IP::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' ); |
| 43 | + |
43 | 44 | $this->assertTrue( IP::isIPv6( 'fc:100::' ) ); |
44 | 45 | $this->assertTrue( IP::isIPv6( 'fc:100:a::' ) ); |
45 | 46 | $this->assertTrue( IP::isIPv6( 'fc:100:a:d::' ) ); |
46 | 47 | $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1::' ) ); |
47 | 48 | $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e::' ) ); |
48 | 49 | $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac::' ) ); |
| 50 | + |
49 | 51 | $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); |
50 | 52 | $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); |
51 | 53 | |
52 | 54 | $this->assertFalse( IP::isIPv6( ':::' ) ); |
53 | 55 | $this->assertFalse( IP::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' ); |
| 56 | + |
54 | 57 | $this->assertTrue( IP::isIPv6( '::' ), 'IPv6 zero address' ); |
55 | 58 | $this->assertTrue( IP::isIPv6( '::0' ) ); |
56 | 59 | $this->assertTrue( IP::isIPv6( '::fc' ) ); |
— | — | @@ -59,18 +62,24 @@ |
60 | 63 | $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1' ) ); |
61 | 64 | $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e' ) ); |
62 | 65 | $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e:ac' ) ); |
| 66 | + |
63 | 67 | $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); |
64 | 68 | $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); |
65 | 69 | |
66 | 70 | $this->assertFalse( IP::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' ); |
67 | 71 | $this->assertFalse( IP::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' ); |
68 | 72 | $this->assertFalse( IP::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' ); |
| 73 | + |
69 | 74 | $this->assertTrue( IP::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' ); |
70 | 75 | $this->assertTrue( IP::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); |
71 | 76 | $this->assertTrue( IP::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) ); |
72 | 77 | $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); |
73 | 78 | $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' ); |
74 | 79 | $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); |
| 80 | + $this->assertTrue( IP::isIPv6( '2001::df'), 'IPv6 with "::" and 2 words' ); |
| 81 | + $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' ); |
| 82 | + $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' ); |
| 83 | + |
75 | 84 | $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); |
76 | 85 | $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); |
77 | 86 | |
— | — | @@ -111,6 +120,26 @@ |
112 | 121 | $this->assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv6 address" ); |
113 | 122 | } |
114 | 123 | } |
| 124 | + // test with some abbreviations |
| 125 | + $this->assertFalse( IP::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' ); |
| 126 | + $this->assertFalse( IP::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); |
| 127 | + $this->assertFalse( IP::isValid( 'fc:300' ), 'IPv6 with only 2 words' ); |
| 128 | + $this->assertFalse( IP::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' ); |
| 129 | + |
| 130 | + $this->assertTrue( IP::isValid( 'fc:100::' ) ); |
| 131 | + $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e::' ) ); |
| 132 | + $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e:ac::' ) ); |
| 133 | + |
| 134 | + $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' ); |
| 135 | + $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); |
| 136 | + $this->assertTrue( IP::isValid( '2001::df'), 'IPv6 with "::" and 2 words' ); |
| 137 | + $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' ); |
| 138 | + $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' ); |
| 139 | + $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); |
| 140 | + $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); |
| 141 | + |
| 142 | + $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); |
| 143 | + $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); |
115 | 144 | } |
116 | 145 | |
117 | 146 | public function testInvalidIPs() { |
Index: trunk/phase3/includes/IP.php |
— | — | @@ -39,17 +39,18 @@ |
40 | 40 | ':(?::|(?::' . RE_IPV6_WORD . '){1,7})' . |
41 | 41 | '|' . // ends with "::" (except "::") |
42 | 42 | RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){0,6}::' . |
43 | | - '|' . // contains no "::" |
44 | | - RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){7}' . |
45 | | - '|' . // contains one "::" in the middle and 2 words |
46 | | - RE_IPV6_WORD . '::' . RE_IPV6_WORD . |
47 | | - '|' . // contains one "::" in the middle and 3+ words (awkward regex for PCRE 4.0+) |
| 43 | + '|' . // contains one "::" in the middle, ending in "::WORD" |
| 44 | + RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){0,5}' . '::' . RE_IPV6_WORD . |
| 45 | + '|' . // contains one "::" in the middle, not ending in "::WORD" (regex for PCRE 4.0+) |
48 | 46 | RE_IPV6_WORD . '(?::(?P<abn>:(?P<iabn>))?' . RE_IPV6_WORD . '(?!:(?P=abn))){1,5}' . |
49 | 47 | ':' . RE_IPV6_WORD . '(?P=iabn)' . |
50 | 48 | // NOTE: (?!(?P=abn)) fails iff "::" used twice; (?P=iabn) passes iff a "::" was found. |
51 | | - // RegExp (PCRE 7.2+ only) for last 2 cases that allows easy regex concatenation: |
52 | | - #RE_IPV6_WORD . '(?::((?(-1)|:))?' . RE_IPV6_WORD . '){1,6}(?(-2)|^)' . |
| 49 | + '|' . // contains no "::" |
| 50 | + RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){7}' . |
53 | 51 | ')' |
| 52 | + // NOTE: With PCRE 7.2+, we can combine the last two cases into one regex: |
| 53 | + // RE_IPV6_WORD . '(?::((?(-1)|:))?' . RE_IPV6_WORD . '){1,6}(?(-2)|^)' |
| 54 | + // This also improves regex concatenation by using relative references. |
54 | 55 | ); |
55 | 56 | // An IPv6 block is an IP address and a prefix (d1 to d128) |
56 | 57 | define( 'RE_IPV6_BLOCK', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX ); |