@@ -141,8 +141,8 @@ public static String decode(String toDecode, CharacterSet characterSet) {
141141 try {
142142 result = (characterSet == null ) ? toDecode : java .net .URLDecoder .decode (toDecode , characterSet .getName ());
143143 } catch (UnsupportedEncodingException uee ) {
144- Context .getCurrentLogger ().log (Level .WARNING ,
145- "Unable to decode the string with the " + characterSet .getName () + " character set." , uee );
144+ Context .getCurrentLogger ().log (Level .WARNING , uee ,
145+ () -> "Unable to decode the string with the " + characterSet .getName () + " character set." );
146146 }
147147
148148 return result ;
@@ -2855,50 +2855,36 @@ private void validateAuthority(String authority) {
28552855 return ;
28562856 }
28572857
2858+ authority = validateUserInfoAndReturnRemaining (authority );
2859+ authority = validateIpV6AndReturnRemaining (authority );
2860+
2861+ int portIndex = authority .indexOf (':' );
2862+ if (portIndex != -1 ) {
2863+ validateHostPort (authority .substring (portIndex + 1 ));
2864+ }
2865+ }
2866+
2867+ /**
2868+ * Validate the user info part of the authority, and return the remaining part of the authority.
2869+ */
2870+ private String validateUserInfoAndReturnRemaining (final String authority ) {
28582871 int atIndex = authority .indexOf ('@' );
2859- int ipV6StartIndex = authority .indexOf ('[' );
28602872
28612873 if (atIndex != -1 ) {
2874+ final int ipV6StartIndex = authority .indexOf ('[' );
2875+
28622876 if (ipV6StartIndex != -1 ) {
2863- if (atIndex < ipV6StartIndex ) {
2864- authority = authority .substring (atIndex + 1 );
2865- ipV6StartIndex -= atIndex + 1 ;
2866- } else {
2877+ if (atIndex >= ipV6StartIndex ) {
28672878 throw new IllegalArgumentException ("Invalid authority format" );
28682879 }
2869- } else {
2870- authority = authority .substring (atIndex + 1 );
28712880 }
2881+ return authority .substring (atIndex + 1 );
28722882 }
28732883
2874- if (ipV6StartIndex == -1 ) {
2875- int portIndex = authority .indexOf (':' );
2876-
2877- if (portIndex != -1 ) {
2878- validateHostPort (authority .substring (portIndex + 1 ));
2879- }
2880- } else if (ipV6StartIndex == 0 ) {
2881- int ipV6EndIndex = authority .indexOf (']' );
2882- if (ipV6EndIndex == -1 ) {
2883- throw new IllegalArgumentException ("Invalid IPv6 address format: no closing bracket" );
2884- } else {
2885- validateIPv6 (authority .substring (0 , ipV6EndIndex + 1 ));
2886- if (ipV6EndIndex + 1 < authority .length ()) {
2887- if (authority .charAt (ipV6EndIndex + 1 ) == ':' ) {
2888- validateHostPort (authority .substring (ipV6EndIndex + 2 ));
2889- } else {
2890- throw new IllegalArgumentException (
2891- "Invalid authority format: unexpected character after closing bracket" );
2892- }
2893- }
2894- }
2895- } else {
2896- throw new IllegalArgumentException (
2897- "Invalid IPv6 address format: unexpected character before opening bracket" );
2898- }
2884+ return authority ;
28992885 }
29002886
2901- /**
2887+ /**
29022888 * Validate an host port.
29032889 *
29042890 * @param hostPort The port to validate.
@@ -2913,59 +2899,85 @@ private void validateHostPort(final String hostPort) {
29132899 }
29142900 }
29152901
2902+ private String validateIpV6AndReturnRemaining (String authority ) {
2903+ int ipV6StartIndex = authority .indexOf ('[' );
2904+ int ipV6EndIndex = authority .indexOf (']' );
2905+
2906+ if (ipV6StartIndex > 0 ) {
2907+ throw new IllegalArgumentException (
2908+ "Invalid IPv6 address format: unexpected character before opening bracket" );
2909+ }
2910+ if (ipV6StartIndex == -1 ) {
2911+ return authority ;
2912+ }
2913+
2914+ if (ipV6EndIndex == -1 ) {
2915+ throw new IllegalArgumentException ("Invalid IPv6 address format: no closing bracket" );
2916+ }
2917+ validateIpV6 (authority .substring (1 , ipV6EndIndex )); // trim brackets
2918+
2919+ if (ipV6EndIndex + 1 < authority .length ()) {
2920+ if (authority .charAt (ipV6EndIndex + 1 ) != ':' ) {
2921+ throw new IllegalArgumentException (
2922+ "Invalid authority format: unexpected character after closing bracket" );
2923+ }
2924+ }
2925+
2926+ return authority .substring (ipV6EndIndex + 1 );
2927+ }
2928+
29162929 /**
29172930 * Validate an IP v6 according to RFC 2373.
2918- *
2919- * @param ipv6 The IP v6 to validate.
29202931 */
2921- private void validateIPv6 (String ipv6 ) {
2922- if (ipv6 == null || ipv6 .isEmpty ()) {
2932+ private void validateIpV6 (String ipV6 ) {
2933+ if (ipV6 == null || ipV6 .isEmpty ()) {
29232934 throw new IllegalArgumentException ("Invalid IPv6 address" );
29242935 }
29252936
2926- if (ipv6 .startsWith ("[" )) {
2927- ipv6 = ipv6 .substring (1 );
2928- }
2929- if (ipv6 .endsWith ("]" )) {
2930- ipv6 = ipv6 .substring (0 , ipv6 .length () - 1 );
2931- }
29322937
29332938 // Check for double colon compression (only one allowed)
29342939 int doubleColonCount = 0 ;
2935- int idx = ipv6 .indexOf ("::" );
2940+ int idx = ipV6 .indexOf ("::" );
29362941 while (idx != -1 ) {
29372942 doubleColonCount ++;
2938- idx = ipv6 .indexOf ("::" , idx + 2 );
2943+ idx = ipV6 .indexOf ("::" , idx + 2 );
29392944 }
29402945 if (doubleColonCount > 1 ) {
29412946 throw new IllegalArgumentException ("Invalid IPv6 address format" );
29422947 }
29432948
2944- String [] parts = ipv6 .split (":" , -1 );
2949+ String [] parts = ipV6 .split (":" , -1 );
29452950 int maxParts = 8 ;
29462951
29472952 if (parts .length > maxParts ) {
29482953 throw new IllegalArgumentException ("Invalid IPv6 address format" );
29492954 }
29502955
29512956 for (String part : parts ) {
2952- if (part .isEmpty () && doubleColonCount == 0 ) {
2957+ validateIpV6Part (part , doubleColonCount );
2958+ }
2959+ }
2960+
2961+ /**
2962+ * Validate a segment of an IP V6 according to RFC 2373.
2963+ */
2964+ private void validateIpV6Part (final String part , final int doubleColonCount ) {
2965+ if (part .isEmpty () && doubleColonCount == 0 ) {
2966+ throw new IllegalArgumentException ("Invalid IPv6 address format" );
2967+ }
2968+ if (!part .isEmpty ()) {
2969+ if (part .length () > 4 ) {
29532970 throw new IllegalArgumentException ("Invalid IPv6 address format" );
29542971 }
2955- if (! part .isEmpty ()) {
2956- if (part . length () > 4 ) {
2972+ for ( char c : part .toCharArray ()) {
2973+ if (! isAlpha ( c ) && ! isDigit ( c ) ) {
29572974 throw new IllegalArgumentException ("Invalid IPv6 address format" );
29582975 }
2959- for (char c : part .toCharArray ()) {
2960- if (!isAlpha (c ) && !isDigit (c )) {
2961- throw new IllegalArgumentException ("Invalid IPv6 address format" );
2962- }
2963- }
29642976 }
29652977 }
29662978 }
29672979
2968- /**
2980+ /**
29692981 * Validate a scheme according to RFC 3986.
29702982 *
29712983 * @param scheme The scheme to validate.
0 commit comments