@@ -12,9 +12,6 @@ public final class HeaderUtils {
1212 // Header name lookup table: 0=invalid, 1=valid lower, 2=valid upper.
1313 private static final byte [] HEADER_NAME_TABLE = new byte [128 ];
1414
15- // Header value lookup table: true = allowed character
16- private static final boolean [] VALID_VALUE_CHAR = new boolean [256 ];
17-
1815 static {
1916 for (char c = 'a' ; c <= 'z' ; c ++) {
2017 HEADER_NAME_TABLE [c ] = 1 ;
@@ -26,16 +23,6 @@ public final class HeaderUtils {
2623 for (int i = 0 ; i < validChars .length (); i ++) {
2724 HEADER_NAME_TABLE [validChars .charAt (i )] = 1 ;
2825 }
29-
30- // Valid value chars per RFC 7230 field-content: SP, HTAB, VCHAR, obs-text
31- VALID_VALUE_CHAR [' ' ] = true ;
32- VALID_VALUE_CHAR ['\t' ] = true ;
33- for (int c = 0x21 ; c <= 0x7E ; c ++) {
34- VALID_VALUE_CHAR [c ] = true ;
35- }
36- for (int c = 0x80 ; c <= 0xFF ; c ++) {
37- VALID_VALUE_CHAR [c ] = true ;
38- }
3926 }
4027
4128 private HeaderUtils () {}
@@ -102,25 +89,36 @@ static String normalizeName(String name) {
10289 * @throws IllegalArgumentException if the value contains invalid characters
10390 */
10491 public static String normalizeValue (String value ) {
105- // Simulate String.trim(), but we only want to trim leading and trailing ' ' and '\t'.
10692 int len = value .length ();
107- int end = len - 1 ;
108- int start = trimStart (value , end );
109- end = trimEnd (value , start );
110- if (start > end ) {
111- return "" ;
93+ if (len == 0 ) {
94+ return value ;
11295 }
11396
114- for (int i = start ; i <= end ; i ++) {
97+ // Peek at the boundaries to detect whether trimming is needed.
98+ char first = value .charAt (0 );
99+ char last = value .charAt (len - 1 );
100+ boolean trimNeeded = first == ' ' || first == '\t' || last == ' ' || last == '\t' ;
101+
102+ // Ensure valid chars match obs-text
103+ for (int i = 0 ; i < len ; i ++) {
115104 char c = value .charAt (i );
116- if (c > 255 || ! VALID_VALUE_CHAR [ c ] ) {
105+ if (c > 0xFF || ( c < 0x20 && c != '\t' ) || c == 0x7F ) {
117106 throw invalidHeaderValueChar (value );
118107 }
119108 }
120109
121- return (start == 0 && end == len - 1 )
122- ? value
123- : value .substring (start , end + 1 );
110+ if (!trimNeeded ) {
111+ return value ;
112+ }
113+
114+ int end = len - 1 ;
115+ int start = trimStart (value , end );
116+ end = trimEnd (value , start );
117+ if (start > end ) {
118+ return "" ;
119+ }
120+
121+ return value .substring (start , end + 1 );
124122 }
125123
126124 private static int trimStart (String s , int end ) {
0 commit comments