@@ -37,12 +37,12 @@ public class InetAddresses {
3737
3838 public static boolean isInetAddress (String ipString ) {
3939 XContentString .UTF8Bytes bytes = new Text (ipString ).bytes ();
40- return ipStringToBytes (bytes .bytes (), bytes .offset (), bytes .length ()) != null ;
40+ return ipStringToBytes (bytes .bytes (), bytes .offset (), bytes .length (), false ) != null ;
4141 }
4242
4343 public static String getIpOrHost (String ipString ) {
4444 XContentString .UTF8Bytes utf8Bytes = new Text (ipString ).bytes ();
45- byte [] bytes = ipStringToBytes (utf8Bytes .bytes (), utf8Bytes .offset (), utf8Bytes .length ());
45+ byte [] bytes = ipStringToBytes (utf8Bytes .bytes (), utf8Bytes .offset (), utf8Bytes .length (), false );
4646 if (bytes == null ) { // is not InetAddress
4747 return ipString ;
4848 }
@@ -59,15 +59,15 @@ public static String getIpOrHost(String ipString) {
5959 */
6060 public static byte [] encodeAsIpv6 (XContentString ipString ) {
6161 XContentString .UTF8Bytes uft8Bytes = ipString .bytes ();
62- byte [] address = ipStringToBytes (uft8Bytes .bytes (), uft8Bytes .offset (), uft8Bytes .length ());
62+ byte [] address = ipStringToBytes (uft8Bytes .bytes (), uft8Bytes .offset (), uft8Bytes .length (), true );
6363 // The argument was malformed, i.e. not an IP string literal.
6464 if (address == null ) {
6565 throw new IllegalArgumentException (String .format (Locale .ROOT , "'%s' is not an IP string literal." , ipString .string ()));
6666 }
6767 return CIDRUtils .encode (address );
6868 }
6969
70- private static byte [] ipStringToBytes (byte [] ipUtf8 , int offset , int length ) {
70+ private static byte [] ipStringToBytes (byte [] ipUtf8 , int offset , int length , boolean asIpv6 ) {
7171 // Make a first pass to categorize the characters in this string.
7272 boolean hasColon = false ;
7373 boolean hasDot = false ;
@@ -103,7 +103,7 @@ private static byte[] ipStringToBytes(byte[] ipUtf8, int offset, int length) {
103103 }
104104 return textToNumericFormatV6 (ipUtf8 , offset , length );
105105 } else if (hasDot ) {
106- return textToNumericFormatV4 (ipUtf8 , offset , length );
106+ return textToNumericFormatV4 (ipUtf8 , offset , length , asIpv6 );
107107 }
108108 return null ;
109109 }
@@ -116,7 +116,7 @@ private static byte[] convertDottedQuadToHex(byte[] ipUtf8, int offset, int leng
116116 }
117117 }
118118 assert quadOffset >= 0 : "Expected at least one colon in dotted quad IPv6 address" ;
119- byte [] quad = textToNumericFormatV4 (ipUtf8 , offset + quadOffset , length - quadOffset );
119+ byte [] quad = textToNumericFormatV4 (ipUtf8 , offset + quadOffset , length - quadOffset , false );
120120 if (quad == null ) {
121121 return null ;
122122 }
@@ -130,15 +130,25 @@ private static byte[] convertDottedQuadToHex(byte[] ipUtf8, int offset, int leng
130130 return result ;
131131 }
132132
133- private static byte [] textToNumericFormatV4 (byte [] ipUtf8 , int offset , int length ) {
134- byte [] bytes = new byte [IPV4_PART_COUNT ];
135- byte octet = 0 ;
133+ private static byte [] textToNumericFormatV4 (byte [] ipUtf8 , int offset , int length , boolean asIpv6 ) {
134+ byte [] bytes ;
135+ byte octet ;
136+ if (asIpv6 ) {
137+ bytes = new byte [IPV6_PART_COUNT * 2 ];
138+ System .arraycopy (CIDRUtils .IPV4_PREFIX , 0 , bytes , 0 , CIDRUtils .IPV4_PREFIX .length );
139+ octet = (byte ) CIDRUtils .IPV4_PREFIX .length ;
140+ } else {
141+ bytes = new byte [IPV4_PART_COUNT ];
142+ octet = 0 ;
143+ }
136144 byte digits = 0 ;
137145 int current = 0 ;
138146 for (int i = offset ; i < offset + length ; i ++) {
139147 byte c = ipUtf8 [i ];
140148 if (c == '.' ) {
141- if (octet > 3 /* too many octets */ || digits == 0 /* empty octet */ || current > 255 /* octet is outside a byte range */ ) {
149+ if (octet >= bytes .length /* too many octets */
150+ || digits == 0 /* empty octet */
151+ || current > 255 /* octet is outside a byte range */ ) {
142152 return null ;
143153 }
144154 bytes [octet ++] = (byte ) current ;
@@ -154,7 +164,9 @@ private static byte[] textToNumericFormatV4(byte[] ipUtf8, int offset, int lengt
154164 return null ;
155165 }
156166 }
157- if (octet != 3 /* too many octets */ || digits == 0 /* empty octet */ || current > 255 /* octet is outside a byte range */ ) {
167+ if (octet != bytes .length - 1 /* too many or too few octets */
168+ || digits == 0 /* empty octet */
169+ || current > 255 /* octet is outside a byte range */ ) {
158170 return null ;
159171 }
160172 bytes [octet ] = (byte ) current ;
@@ -419,7 +431,7 @@ public static InetAddress forString(XContentString.UTF8Bytes bytes) {
419431 * which utilizes a more efficient implementation for parsing the IP address.
420432 */
421433 public static InetAddress forString (byte [] ipUtf8 , int offset , int length ) {
422- byte [] addr = ipStringToBytes (ipUtf8 , offset , length );
434+ byte [] addr = ipStringToBytes (ipUtf8 , offset , length , false );
423435
424436 // The argument was malformed, i.e. not an IP string literal.
425437 if (addr == null ) {
0 commit comments