From: markt Date: Tue, 4 Jan 2011 19:20:28 +0000 (+0000) Subject: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49000 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=65183e7903f03626ebfcd7e8d49ed34d20b7742d;p=tomcat7.0 Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49000 Make accepting name only cookies configurable, defaulting to disabled. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1055143 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/tomcat/util/http/CookieSupport.java b/java/org/apache/tomcat/util/http/CookieSupport.java index e03043c67..6456de360 100644 --- a/java/org/apache/tomcat/util/http/CookieSupport.java +++ b/java/org/apache/tomcat/util/http/CookieSupport.java @@ -60,6 +60,11 @@ public final class CookieSupport { public static final boolean FWD_SLASH_IS_SEPARATOR; /** + * If true, name only cookies will be permitted. + */ + public static final boolean ALLOW_NAME_ONLY; + + /** * The list of separators that apply to version 0 cookies. To quote the * spec, these are comma, semi-colon and white-space. The HTTP spec * definition of linear white space is [CRLF] 1*( SP | HT ) @@ -106,6 +111,11 @@ public final class CookieSupport { Boolean.valueOf(fwdSlashIsSeparator).booleanValue(); } + ALLOW_NAME_ONLY = Boolean.valueOf(System.getProperty( + "org.apache.tomcat.util.http.ServerCookie.ALLOW_NAME_ONLY", + "false")).booleanValue(); + + /* Excluding the '/' char by default violates the RFC, but it looks like a lot of people put '/' diff --git a/java/org/apache/tomcat/util/http/Cookies.java b/java/org/apache/tomcat/util/http/Cookies.java index 39e8edab3..857d0fdd8 100644 --- a/java/org/apache/tomcat/util/http/Cookies.java +++ b/java/org/apache/tomcat/util/http/Cookies.java @@ -422,6 +422,11 @@ public final class Cookies { // extends MultiMap { log.info("Cookies: Unknown Special Cookie"); } else { // Normal Cookie + if (valueStart == -1 && !CookieSupport.ALLOW_NAME_ONLY) { + // Skip name only cookies if not supported + continue; + } + sc = addCookie(); sc.setVersion( version ); sc.getName().setBytes( bytes, nameStart, diff --git a/test/org/apache/tomcat/util/http/TestCookies.java b/test/org/apache/tomcat/util/http/TestCookies.java index 0834d3463..a8151b3c9 100644 --- a/test/org/apache/tomcat/util/http/TestCookies.java +++ b/test/org/apache/tomcat/util/http/TestCookies.java @@ -102,12 +102,12 @@ public class TestCookies extends TestCase { public void testNameOnlyCookies() throws Exception { // Bug 49000 - test("fred=1; jim=2; bob", "fred", "1", "jim", "2", "bob", ""); - test("fred=1; jim=2; bob; george=3", "fred", "1", "jim", "2", "bob", "", + test("fred=1; jim=2; bob", "fred", "1", "jim", "2"); + test("fred=1; jim=2; bob; george=3", "fred", "1", "jim", "2", "george", "3"); test("fred=1; jim=2; bob=; george=3", "fred", "1", "jim", "2", - "bob", "", "george", "3"); - test("fred=1; jim=2; bob=", "fred", "1", "jim", "2", "bob", ""); + "george", "3"); + test("fred=1; jim=2; bob=", "fred", "1", "jim", "2"); } diff --git a/test/org/apache/tomcat/util/http/TestCookiesAllowNameOnly.java b/test/org/apache/tomcat/util/http/TestCookiesAllowNameOnly.java new file mode 100644 index 000000000..8a9513737 --- /dev/null +++ b/test/org/apache/tomcat/util/http/TestCookiesAllowNameOnly.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.http; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.catalina.Context; +import org.apache.catalina.startup.SimpleHttpClient; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; + +public class TestCookiesAllowNameOnly extends TomcatBaseTest{ + + private static final String COOKIE_WITH_NAME_ONLY_1 = "bob"; + private static final String COOKIE_WITH_NAME_ONLY_2 = "bob="; + + public void testWithEquals() throws Exception { + System.setProperty( + "org.apache.tomcat.util.http.ServerCookie.ALLOW_NAME_ONLY", + "true"); + + TestCookieNameOnlyClient client = new TestCookieNameOnlyClient(); + client.doRequest(); + } + + private class TestCookieNameOnlyClient extends SimpleHttpClient { + + + private void doRequest() throws Exception { + Tomcat tomcat = getTomcatInstance(); + Context root = tomcat.addContext("", TEMP_DIR); + Tomcat.addServlet(root, "Simple", new SimpleServlet()); + root.addServletMapping("/test", "Simple"); + + tomcat.start(); + // Open connection + setPort(tomcat.getConnector().getPort()); + connect(); + + String[] request = new String[1]; + request[0] = + "GET /test HTTP/1.0" + CRLF + + "Cookie: " + COOKIE_WITH_NAME_ONLY_1 + CRLF + + "Cookie: " + COOKIE_WITH_NAME_ONLY_2 + CRLF + CRLF; + setRequest(request); + processRequest(true); // blocks until response has been read + String response = getResponseBody(); + + // Close the connection + disconnect(); + reset(); + tomcat.stop(); + // Need the extra equals since cookie 1 is just the name + assertEquals(COOKIE_WITH_NAME_ONLY_1 + "=" + + COOKIE_WITH_NAME_ONLY_2, response); + } + + @Override + public boolean isResponseBodyOK() { + return true; + } + + } + + + private static class SimpleServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + Cookie cookies[] = req.getCookies(); + for (Cookie cookie : cookies) { + resp.getWriter().write(cookie.getName() + "=" + + cookie.getValue()); + } + resp.flushBuffer(); + } + + } + +} diff --git a/webapps/docs/config/systemprops.xml b/webapps/docs/config/systemprops.xml index 98684bbe9..467b15471 100644 --- a/webapps/docs/config/systemprops.xml +++ b/webapps/docs/config/systemprops.xml @@ -366,8 +366,7 @@ else the default value will be false.

- +

If this is true then the requirements of the Servlet specification that Cookie names must adhere to RFC2109 (no use of separators) will be enforced.

@@ -376,6 +375,14 @@ else the default value will be false.

+ +

If this is true then the requirements of the cookie specifications + that cookies must have values will be enforced and cookies consisting only + of a name but no value will be ignored.

+

If not specified, the default specification compliant value of + false will be used.

+
+