diff --git a/core/src/main/java/io/undertow/util/Cookies.java b/core/src/main/java/io/undertow/util/Cookies.java index a892900734..3c3345fe21 100644 --- a/core/src/main/java/io/undertow/util/Cookies.java +++ b/core/src/main/java/io/undertow/util/Cookies.java @@ -226,14 +226,13 @@ public static void parseRequestCookies(int maxCookies, boolean allowEqualInValue static Map parseRequestCookies(int maxCookies, boolean allowEqualInValue, List cookies, boolean commaIsSeperator) { return parseRequestCookies(maxCookies, allowEqualInValue, cookies, commaIsSeperator, LegacyCookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0); } - - static Map parseRequestCookies(int maxCookies, boolean allowEqualInValue, List cookies, boolean commaIsSeperator, boolean allowHttpSepartorsV0) { + static Map parseRequestCookies(int maxCookies, boolean allowEqualInValue, List cookies, boolean commaIsSeperator, boolean allowHttpSepartorsV0, boolean rfc6265ParsingDisabled){ if (cookies == null) { return new TreeMap<>(); } final Set parsedCookies = new HashSet<>(); for (String cookie : cookies) { - parseCookie(cookie, parsedCookies, maxCookies, allowEqualInValue, commaIsSeperator, allowHttpSepartorsV0, true); + parseCookie(cookie, parsedCookies, maxCookies, allowEqualInValue, commaIsSeperator, allowHttpSepartorsV0, rfc6265ParsingDisabled); } final Map retVal = new TreeMap<>(); @@ -242,6 +241,9 @@ static Map parseRequestCookies(int maxCookies, boolean allowEqua } return retVal; } + static Map parseRequestCookies(int maxCookies, boolean allowEqualInValue, List cookies, boolean commaIsSeperator, boolean allowHttpSepartorsV0) { + return parseRequestCookies(maxCookies, allowEqualInValue, cookies, commaIsSeperator, allowHttpSepartorsV0, true); + } static void parseRequestCookies(int maxCookies, boolean allowEqualInValue, List cookies, Set parsedCookies, boolean commaIsSeperator, boolean allowHttpSepartorsV0, boolean rfc6265ParsingDisabled) { if (cookies != null) { @@ -320,13 +322,40 @@ private static void parseCookie(final String cookie, final Set parsedCoo case 3: { //extract quoted value if (c == '"') { + int index = i; if (!rfc6265ParsingDisabled && inQuotes) { start = start - 1; - inQuotes = false; i++; - cookieCount = createCookie(name, containsEscapedQuotes ? unescapeDoubleQuotes(cookie.substring(start, i)) : cookie.substring(start, i), maxCookies, cookieCount, cookies, additional); + } + inQuotes = false; + final boolean existed = cookies.containsKey(name); + cookieCount = createCookie(name, containsEscapedQuotes ? unescapeDoubleQuotes(cookie.substring(start, i)) : cookie.substring(start, i), maxCookies, cookieCount, cookies, additional); + //if there is more, make sure next is separator + if (index + 1 < cookie.length() && (cookie.charAt(index + 1) == ';' // Cookie: key="\"; key2=... + || (commaIsSeperator && cookie.charAt(index + 1) == ',')) // Cookie: key="\", key2=... + || index+1 == cookie.length()) { //end of cookie + //adjust position to delimiter and let state == 0 spin again whole thing + i++; } else { - cookieCount = createCookie(name, containsEscapedQuotes ? unescapeDoubleQuotes(cookie.substring(start, i)) : cookie.substring(start, i), maxCookies, cookieCount, cookies, additional); + if(UndertowLogger.REQUEST_LOGGER.isTraceEnabled()) { + UndertowLogger.REQUEST_LOGGER.trace("Ignoring invalid cookies in header " + cookie); + } + if(!existed) { + //RN we dont add copy, so lets not remove proper cookie that we stored + //prior to this one + cookies.remove(name); + } + additional.remove(name); + //seek next separator + while(i cookies = Cookies.parseRequestCookies(2, false, Arrays.asList("CUSTOMER=\"WILE_E_COYOTE\", SHIPPING=FEDEX" ), true, LegacyCookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0, false); + Assert.assertEquals(2, cookies.size()); + Cookie cookie = cookies.get("CUSTOMER"); + Assert.assertNotNull(cookie); + Assert.assertEquals("\"WILE_E_COYOTE\"", cookie.getValue()); + cookie = cookies.get("SHIPPING"); + Assert.assertNotNull(cookie); + Assert.assertEquals("FEDEX", cookie.getValue()); + + //also make sure semi colon works as normal + cookies = Cookies.parseRequestCookies(2, false, Arrays.asList("CUSTOMER=\"WILE_E_COYOTE\"; SHIPPING=FEDEX" ), true, LegacyCookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0, false); + Assert.assertEquals(2, cookies.size()); + cookie = cookies.get("CUSTOMER"); + Assert.assertNotNull(cookie); + Assert.assertEquals("\"WILE_E_COYOTE\"", cookie.getValue()); + cookie = cookies.get("SHIPPING"); + Assert.assertNotNull(cookie); + Assert.assertEquals("FEDEX", cookie.getValue()); + + cookies = Cookies.parseRequestCookies(5, false, Arrays.asList("CUSTOMER=\"WILE_E_COYOTE\", BAD_CUSTOMER=\"APPLE\" IGNORED=PART, SHIPPING=FEDEX" ), true, LegacyCookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0, false); + Assert.assertEquals(2, cookies.size()); + cookie = cookies.get("CUSTOMER"); + Assert.assertNotNull(cookie); + Assert.assertEquals("\"WILE_E_COYOTE\"", cookie.getValue()); + cookie = cookies.get("SHIPPING"); + Assert.assertNotNull(cookie); + Assert.assertEquals("FEDEX", cookie.getValue()); } @Test