Subject: | Allows leading : |
Strings starting with a spurrious ':' are accepted by Regex::IPv6_re,
but should not be.
Example: The string ":2001::" is accepted by Regexp::IPv6_re, but
should not be.
perl -MRegexp::IPv6 -e1 -d
Loading DB routines from perl5db.pl version 1.33
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(-e:1): 1
DB<1> x ':2001::' =~ $Regexp::IPv6::IPv6_re
0 1
':2001:db8::1234' will also fail, as will any other valid IPv6 address
preceded by a ':'
We can see the initial ':' in the compiled string:
DB<13> x "$Regexp::IPv6::IPv6_re"
0 '(?^::<<--HERE(?::[0-9a-fA-F]{1,4}){0,5}(?:(?::[0-9a-fA-F]{1,4}){1,2}
|:(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|
[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-
5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})))|[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:
(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-
F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}|:)|(?::(?:[0-9a-fA-F]
{1,4})?|(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4]
[0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.]
(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))))|:(?:(?:(?:25[0-5]|2[0-4][0-
9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25
[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]
{1,2}))|[0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4})?|))|(?::(?:(?:25[0-5]|2[0-
4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.]
(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?
[0-9]{1,2}))|:[0-9a-fA-F]{1,4}(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]
{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-
9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|(?::[0-
9a-fA-F]{1,4}){0,2})|:))|(?:(?::[0-9a-fA-F]{1,4}){0,2}(?::(?:(?:25[0-5]
|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]
{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-
9]|[0-1]?[0-9]{1,2}))|(?::[0-9a-fA-F]{1,4}){1,2})|:))|(?:(?::[0-9a-fA-F]
{1,4}){0,3}(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]
|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]
{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|(?::[0-9a-fA-F]{1,4})
{1,2})|:))|(?:(?::[0-9a-fA-F]{1,4}){0,4}(?::(?:(?:25[0-5]|2[0-4][0-9]|
[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-
5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]
{1,2}))|(?::[0-9a-fA-F]{1,4}){1,2})|:)))'
This Regexp seems to correctly validate all IPv6 addresses (except
those with zone-ids, which are not desirable in some environments and
are easy to add to a regexp that includes this one.
qr{(?:::|(?:(?:[[:xdigit:]]{1,4}:){0,6}[[:xdigit:]]{1,4}::|(?:(?:
[[:xdigit:]]{1,4}:){7}|::(?:[[:xdigit:]]{1,4}:){0,6}|[[:xdigit:]]{1,4}::
(?:[[:xdigit:]]{1,4}:){0,5}|(?:[[:xdigit:]]{1,4}:)?[[:xdigit:]]{1,4}::
(?:[[:xdigit:]]{1,4}:){0,4}|(?:[[:xdigit:]]{1,4}:){0,2}[[:xdigit:]]
{1,4}::(?:[[:xdigit:]]{1,4}:){0,3}|(?:[[:xdigit:]]{1,4}:){0,3}
[[:xdigit:]]{1,4}::(?:[[:xdigit:]]{1,4}:){0,2}|(?:[[:xdigit:]]{1,4}:)
{0,4}[[:xdigit:]]{1,4}::(?:[[:xdigit:]]{1,4}:)?|(?:[[:xdigit:]]{1,4}:)
{0,5}[[:xdigit:]]{1,4}::)[[:xdigit:]]{1,4}|(?:::|(?:[[:xdigit:]]{1,4}:)
{6}|(?:[[:xdigit:]]{1,4}:){1,4}:(?:[[:xdigit:]]{1,4}:){1,2}|(?:
[[:xdigit:]]{1,4}:){1,3}:(?:[[:xdigit:]]{1,4}:){1,3}|(?:[[:xdigit:]]
{1,4}:){1,2}:(?:[[:xdigit:]]{1,4}:){1,4}|(?:[[:xdigit:]]{1,4})?::(?:
[[:xdigit:]]{1,4}:){1,5}|(?:[[:xdigit:]]{1,4}:){1,5}(?::[[:xdigit:]]
{1,4})?:)(?:(?:25[0-5]|1[\d]{2}|(?:2[0-4]|[1-9])?[\d])\.){3}(?:25[0-5]|1
[\d]{2}|(?:2[0-4]|[1-9])?[\d])))}o;
If the unspecified address (::) is not desired, it can be removed (it's
the first term in this regexp), or the application can easily compare
the input to '::'.
Zone-ids are not standardized (RFC 4007 says 'any character permitted,
digits required', with is not helpful. Interface names are common, so
the following should work for most cases:
(?:$main_regexp(?:\%[\w_.-]+)?)