< prev index next >

src/jdk.httpserver/share/classes/com/sun/net/httpserver/Headers.java

Print this page
rev 52905 : 8234825: Better Headings for HTTP Servers
Reviewed-by: chegar, dfuchs, igerasim

@@ -80,15 +80,18 @@
                 return key;
             }
             char[] b = key.toCharArray();
             if (b[0] >= 'a' && b[0] <= 'z') {
                 b[0] = (char)(b[0] - ('a' - 'A'));
-            }
+            } else if (b[0] == '\r' || b[0] == '\n')
+                throw new IllegalArgumentException("illegal character in key");
+
             for (int i=1; i<len; i++) {
                 if (b[i] >= 'A' && b[i] <= 'Z') {
                     b[i] = (char) (b[i] + ('a' - 'A'));
-                }
+                } else if (b[i] == '\r' || b[i] == '\n')
+                    throw new IllegalArgumentException("illegal character in key");
             }
             return new String(b);
         }
 
         public int size() {return map.size();}

@@ -126,10 +129,12 @@
             }
             return l.get(0);
         }
 
         public List<String> put(String key, List<String> value) {
+            for (String v : value)
+                checkValue(v);
             return map.put (normalize(key), value);
         }
 
         /**
          * adds the given value to the list of headers

@@ -137,19 +142,44 @@
          * already exist, then it is created
          * @param key the header name
          * @param value the header value to add to the header
          */
         public void add (String key, String value) {
+            checkValue(value);
             String k = normalize(key);
             List<String> l = map.get(k);
             if (l == null) {
                 l = new LinkedList<String>();
                 map.put(k,l);
             }
             l.add (value);
         }
 
+        private static void checkValue(String value) {
+            int len = value.length();
+            for (int i=0; i<len; i++) {
+                char c = value.charAt(i);
+                if (c == '\r') {
+                    // is allowed if it is followed by \n and a whitespace char
+                    if (i >= len - 2) {
+                        throw new IllegalArgumentException("Illegal CR found in header");
+                    }
+                    char c1 = value.charAt(i+1);
+                    char c2 = value.charAt(i+2);
+                    if (c1 != '\n') {
+                        throw new IllegalArgumentException("Illegal char found after CR in header");
+                    }
+                    if (c2 != ' ' && c2 != '\t') {
+                        throw new IllegalArgumentException("No whitespace found after CRLF in header");
+                    }
+                    i+=2;
+                } else if (c == '\n') {
+                    throw new IllegalArgumentException("Illegal LF found in header");
+                }
+            }
+        }
+
         /**
          * sets the given value as the sole header value
          * for the given key. If the mapping does not
          * already exist, then it is created
          * @param key the header name
< prev index next >