Author: markt
Date: Wed Nov 14 12:54:09 2007
New Revision: 595052
URL: http://svn.apache.org/viewvc?rev=595052&view=rev
Log:
Add cookie patch to trunk to keep it up to date
Modified:
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/java/org/apache/catalina/connector/Response.java
tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java
tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java
Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=595052&r1=595051&r2=595052&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Wed Nov 14
12:54:09 2007
@@ -2350,6 +2350,22 @@
cookie.setSecure(true);
}
}
+
+ protected String unescape(String s) {
+ if (s==null) return null;
+ if (s.indexOf('\\') == -1) return s;
+ StringBuffer buf = new StringBuffer();
+ for (int i=0; i<s.length(); i++) {
+ char c = s.charAt(i);
+ if (c!='\\') buf.append(c);
+ else {
+ if (++i >= s.length()) throw new
IllegalArgumentException();//invalid escape, hence invalid cookie
+ c = s.charAt(i);
+ buf.append(c);
+ }
+ }
+ return buf.toString();
+ }
/**
* Parse cookies.
@@ -2369,14 +2385,18 @@
for (int i = 0; i < count; i++) {
ServerCookie scookie = serverCookies.getCookie(i);
try {
- Cookie cookie = new Cookie(scookie.getName().toString(),
- scookie.getValue().toString());
- cookie.setPath(scookie.getPath().toString());
- cookie.setVersion(scookie.getVersion());
+ /*
+ we must unescape the '\\' escape character
+ */
+ Cookie cookie = new Cookie(scookie.getName().toString(),null);
+ int version = scookie.getVersion();
+ cookie.setVersion(version);
+ cookie.setValue(unescape(scookie.getValue().toString()));
+ cookie.setPath(unescape(scookie.getPath().toString()));
String domain = scookie.getDomain().toString();
- if (domain != null) {
- cookie.setDomain(scookie.getDomain().toString());
- }
+ if (domain!=null) cookie.setDomain(unescape(domain));//avoid
NPE
+ String comment = scookie.getComment().toString();
+ cookie.setComment(version==1?unescape(comment):null);
cookies[idx++] = cookie;
} catch(IllegalArgumentException e) {
// Ignore bad cookie
Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=595052&r1=595051&r2=595052&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Wed Nov 14
12:54:09 2007
@@ -955,9 +955,9 @@
if (isCommitted())
return;
- cookies.add(cookie);
-
final StringBuffer sb = new StringBuffer();
+ //web application code can receive a IllegalArgumentException
+ //from the appendCookieValue invokation
if (SecurityUtil.isPackageProtectionEnabled()) {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run(){
@@ -975,12 +975,13 @@
cookie.getPath(), cookie.getDomain(),
cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());
}
-
+ //if we reached here, no exception, cookie is valid
// the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
// RFC2965 is not supported by browsers and the Servlet spec
// asks for 2109.
addHeader("Set-Cookie", sb.toString());
+ cookies.add(cookie);
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java?rev=595052&r1=595051&r2=595052&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java Wed Nov 14
12:54:09 2007
@@ -487,7 +487,7 @@
if (equals( "Version", bytes, nameStart, nameEnd) &&
sc == null) {
// Set version
- if( bytes[valueStart] =='1' && valueEnd == valueStart) {
+ if( bytes[valueStart] =='1' && valueEnd == (valueStart+1))
{
version=1;
} else {
// unknown version (Versioning is not very strict)
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java?rev=595052&r1=595051&r2=595052&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java Wed Nov 14
12:54:09 2007
@@ -145,20 +145,34 @@
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
- if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
+ if (tspecials.indexOf(c) != -1)
return false;
}
return true;
}
+ public static boolean containsCTL(String value, int version) {
+ if( value==null) return false;
+ int len = value.length();
+ for (int i = 0; i < len; i++) {
+ char c = value.charAt(i);
+ if (c < 0x20 || c >= 0x7f) {
+ if (c == 0x09)
+ continue; //allow horizontal tabs
+ return true;
+ }
+ }
+ return false;
+ }
+
+
public static boolean isToken2(String value) {
if( value==null) return true;
int len = value.length();
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
-
- if (c < 0x20 || c >= 0x7f || tspecials2.indexOf(c) != -1)
+ if (tspecials2.indexOf(c) != -1)
return false;
}
return true;
@@ -218,7 +232,7 @@
DateTool.formatOldCookie(new Date(10000));
// TODO RFC2965 fields also need to be passed
- public static void appendCookieValue( StringBuffer buf,
+ public static void appendCookieValue( StringBuffer headerBuf,
int version,
String name,
String value,
@@ -228,6 +242,7 @@
int maxAge,
boolean isSecure )
{
+ StringBuffer buf = new StringBuffer();
// Servlet implementation checks name
buf.append( name );
buf.append("=");
@@ -285,39 +300,54 @@
buf.append ("; Secure");
}
-
+ headerBuf.append(buf);
}
/**
* @deprecated - Not used
*/
- public static void maybeQuote (int version, StringBuffer buf,
- String value) {
+ @Deprecated
+ public static void maybeQuote (int version, StringBuffer buf,String value)
{
// special case - a \n or \r shouldn't happen in any case
if (isToken(value)) {
buf.append(value);
} else {
buf.append('"');
- buf.append(escapeDoubleQuotes(value));
+ buf.append(escapeDoubleQuotes(value,0,value.length()));
buf.append('"');
}
}
+ public static boolean alreadyQuoted (String value) {
+ if (value==null || value.length()==0) return false;
+ return (value.charAt(0)=='\"' && value.charAt(value.length()-1)=='\"');
+ }
+
/**
* Quotes values using rules that vary depending on Cookie version.
* @param version
* @param buf
* @param value
*/
- public static void maybeQuote2 (int version, StringBuffer buf,
- String value) {
- // special case - a \n or \r shouldn't happen in any case
- if (version == 0 && isToken(value) || version == 1 && isToken2(value))
{
- buf.append(value);
- } else {
+ public static void maybeQuote2 (int version, StringBuffer buf, String
value) {
+ if (value==null || value.length()==0) {
+ buf.append("\"\"");
+ }else if (containsCTL(value,version))
+ throw new IllegalArgumentException("Control character in cookie
value, consider BASE64 encoding your value");
+ else if (alreadyQuoted(value)) {
+ buf.append('"');
+ buf.append(escapeDoubleQuotes(value,1,value.length()-1));
buf.append('"');
- buf.append(escapeDoubleQuotes(value));
+ } else if (version==0 && !isToken(value)) {
buf.append('"');
+ buf.append(escapeDoubleQuotes(value,0,value.length()));
+ buf.append('"');
+ } else if (version==1 && !isToken2(value)) {
+ buf.append('"');
+ buf.append(escapeDoubleQuotes(value,0,value.length()));
+ buf.append('"');
+ }else {
+ buf.append(value);
}
}
@@ -326,19 +356,25 @@
* Escapes any double quotes in the given string.
*
* @param s the input string
- *
+ * @param beginIndex start index inclusive
+ * @param endIndex exclusive
* @return The (possibly) escaped string
*/
- private static String escapeDoubleQuotes(String s) {
+ private static String escapeDoubleQuotes(String s, int beginIndex, int
endIndex) {
if (s == null || s.length() == 0 || s.indexOf('"') == -1) {
return s;
}
StringBuffer b = new StringBuffer();
- for (int i = 0; i < s.length(); i++) {
+ for (int i = beginIndex; i < endIndex; i++) {
char c = s.charAt(i);
- if (c == '"')
+ if (c == '\\' ) {
+ b.append(c);
+ //ignore the character after an escape, just append it
+ if (++i>=endIndex) throw new IllegalArgumentException("Invalid
escape character in cookie value.");
+ b.append(s.charAt(i));
+ } else if (c == '"')
b.append('\\').append('"');
else
b.append(c);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]