From 65183e7903f03626ebfcd7e8d49ed34d20b7742d Mon Sep 17 00:00:00 2001
From: markt
Date: Tue, 4 Jan 2011 19:20:28 +0000
Subject: [PATCH] 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
---
.../org/apache/tomcat/util/http/CookieSupport.java | 10 ++
java/org/apache/tomcat/util/http/Cookies.java | 5 +
test/org/apache/tomcat/util/http/TestCookies.java | 8 +-
.../tomcat/util/http/TestCookiesAllowNameOnly.java | 103 +++++++++++++++++++++
webapps/docs/config/systemprops.xml | 11 ++-
5 files changed, 131 insertions(+), 6 deletions(-)
create mode 100644 test/org/apache/tomcat/util/http/TestCookiesAllowNameOnly.java
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.
+
+
--
2.11.0