diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java index 60885ee3470..13929c1d491 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java @@ -180,6 +180,7 @@ public class CookieCutter default: if (i==last) { + // unterminated quote, let's ignore quotes unquoted.setLength(0); inQuoted = false; i--; @@ -201,7 +202,7 @@ public class CookieCutter { case ' ': case '\t': - continue; + break; case ';': if (quoted) @@ -212,6 +213,8 @@ public class CookieCutter } else if(tokenstart>=0 && tokenend>=0) value = hdr.substring(tokenstart, tokenend+1); + else + value = ""; tokenstart = -1; invalue=false; @@ -224,7 +227,7 @@ public class CookieCutter inQuoted=true; if (unquoted==null) unquoted=new StringBuilder(); - continue; + break; } // fall through to default case @@ -284,10 +287,9 @@ public class CookieCutter { name = hdr.substring(tokenstart, tokenend+1); } - tokenstart = -1; invalue=true; - continue; + break; default: if (quoted) @@ -303,17 +305,30 @@ public class CookieCutter tokenstart=i; tokenend=i; if (i==last) - { - name = hdr.substring(tokenstart, tokenend+1); break; - } continue; } } } + if (invalue && i==last && value==null) + { + if (quoted) + { + value = unquoted.toString(); + unquoted.setLength(0); + quoted = false; + } + else if(tokenstart>=0 && tokenend>=0) + { + value = hdr.substring(tokenstart, tokenend+1); + } + else + value = ""; + } + // If after processing the current character we have a value and a name, then it is a cookie - if (value!=null && name!=null) + if (name!=null && value!=null) { try { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java index 7fab2dc1f72..82d7e1754fa 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java @@ -65,7 +65,18 @@ public class CookieCutter_LenientTest // quoted-string = ( <"> *(qdtext) <"> ) // qdtext = > + // lenient with spaces and EOF + ret.add(new String[]{"abc=", "abc", ""}); + ret.add(new String[]{"abc = ", "abc", ""}); + ret.add(new String[]{"abc = ;", "abc", ""}); + ret.add(new String[]{"abc = ; ", "abc", ""}); + ret.add(new String[]{"abc = x ", "abc", "x"}); ret.add(new String[]{"abc=\"\"", "abc", ""}); + ret.add(new String[]{"abc= \"\" ", "abc", ""}); + ret.add(new String[]{"abc= \"x\" ", "abc", "x"}); + ret.add(new String[]{"abc= \"x\" ;", "abc", "x"}); + ret.add(new String[]{"abc= \"x\" ; ", "abc", "x"}); + // The backslash character ("\") may be used as a single-character quoting // mechanism only within quoted-string and comment constructs. // quoted-pair = "\" CHAR @@ -80,7 +91,7 @@ public class CookieCutter_LenientTest // See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-5.2 // Cannot pass names through as javax.servlet.http.Cookie class does not allow them ret.add(new String[]{"$foo=bar", null, null}); - + // Tests that conform to RFC6265 ret.add(new String[]{"abc=foobar!", "abc", "foobar!"}); ret.add(new String[]{"abc=\"foobar!\"", "abc", "foobar!"}); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java index 0165a7692f8..fd693d7738c 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java @@ -1326,7 +1326,7 @@ public class RequestTest "POST / HTTP/1.1\r\n"+ "Host: whatever\r\n"+ "Cookie: name0=value0; name1 = value1 ; name2 = \"\\\"value2\\\"\" \n" + - "Cookie: $Version=2; name3=value3=value3;$path=/path;$domain=acme.com;$port=8080; name4=\"\"; name5 = x ; name6\n" + + "Cookie: $Version=2; name3=value3=value3;$path=/path;$domain=acme.com;$port=8080; name4=\"\"; name5 = ; name6\n" + "Cookie: name7=value7;\n" + "Connection: close\r\n"+ "\r\n"); @@ -1346,7 +1346,7 @@ public class RequestTest assertEquals("name4", cookies.get(4).getName()); assertEquals("", cookies.get(4).getValue()); assertEquals("name5", cookies.get(5).getName()); - assertEquals("x", cookies.get(5).getValue()); + assertEquals("", cookies.get(5).getValue()); // assertEquals("name6", cookies.get(6).getName()); // assertEquals("", cookies.get(6).getValue()); assertEquals("name7", cookies.get(6).getName());