Filip Hanik - Dev Lists wrote: > my suggestion, open a BZ item, attach the patch there, and have the > STATUS file refer to that item
Or put it under people.apache.prg/~your_name/patches/bla.patch. Cheers Jean-Frederic > > Filip > > Filip Hanik - Dev Lists wrote: >> are we really gonna put each patch (the contents of it) in the STATUS >> file, >> this will make the status file unusable pretty quick, wont it? >> >> Filip >> >> [EMAIL PROTECTED] wrote: >>> Author: remm >>> Date: Tue Sep 25 08:22:40 2007 >>> New Revision: 579298 >>> >>> URL: http://svn.apache.org/viewvc?rev=579298&view=rev >>> Log: >>> - Patch update. >>> >>> Modified: >>> tomcat/tc6.0.x/trunk/STATUS >>> >>> Modified: tomcat/tc6.0.x/trunk/STATUS >>> URL: >>> http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS?rev=579298&r1=579297&r2=579298&view=diff >>> >>> ============================================================================== >>> >>> --- tomcat/tc6.0.x/trunk/STATUS (original) >>> +++ tomcat/tc6.0.x/trunk/STATUS Tue Sep 25 08:22:40 2007 >>> @@ -15,7 +15,7 @@ >>> limitations under the License. >>> >>> ================================================================================ >>> >>> >>> -$Id: BUILDING.txt 562769 2007-08-04 22:08:32Z markt $ >>> +$Revision: $ $Date: $ >>> >>> ================================= >>> Apache Tomcat 6.0 Patch Proposals >>> @@ -26,7 +26,551 @@ >>> [ New proposals should be added at the end of the list ] >>> >>> * New cookie parser (third party contribution) >>> - http://people.apache.org/~jfclere/patches/Cookies.java.patch >>> +1: -1: jfclere: The tests must done another way. >>> + >>> +Index: java/org/apache/tomcat/util/http/Cookies.java >>> +=================================================================== >>> +--- java/org/apache/tomcat/util/http/Cookies.java (revision 579106) >>> ++++ java/org/apache/tomcat/util/http/Cookies.java (working copy) >>> +@@ -45,7 +45,28 @@ >>> + boolean unprocessed=true; >>> + + MimeHeaders headers; >>> +- ++ >>> ++ /* >>> ++ List of Separator Characters (see isSeparator()) >>> ++ Excluding the '/' char violates the RFC, but ++ it looks >>> like a lot of people put '/' >>> ++ in unquoted values: '/': ; //47 ++ '\t':9 ' ':32 '\"':34 >>> '\'':39 '(':40 ')':41 ',':44 ':':58 ';':59 '<':60 ++ '=':61 '>':62 >>> '?':63 '@':64 '[':91 '\\':92 ']':93 '{':123 '}':125 >>> ++ */ >>> ++ public static final char SEPARATORS[] = { '\t', ' ', '\"', >>> '\'', '(', ')', ',', ++ ':', ';', '<', '=', '>', '?', '@', >>> '[', '\\', ']', '{', '}' }; >>> ++ >>> ++ protected static final boolean separators[] = new boolean[128]; >>> ++ static { >>> ++ for (int i = 0; i < 128; i++) { >>> ++ separators[i] = false; >>> ++ } >>> ++ for (int i = 0; i < SEPARATORS.length; i++) { >>> ++ separators[SEPARATORS[i]] = true; >>> ++ } >>> ++ } >>> ++ >>> + /** >>> + * Construct a new cookie collection, that will extract >>> + * the information from headers. >>> +@@ -182,181 +203,6 @@ >>> + } >>> + } >>> + +- /** Process a byte[] header - allowing fast processing of the >>> +- * raw data >>> +- */ >>> +- void processCookieHeader( byte bytes[], int off, int len ) >>> +- { >>> +- if( len<=0 || bytes==null ) return; >>> +- int end=off+len; >>> +- int pos=off; >>> +- +- int version=0; //sticky >>> +- ServerCookie sc=null; >>> +- +- >>> +- while( pos<end ) { >>> +- byte cc; >>> +- // [ skip_spaces name skip_spaces "=" skip_spaces value >>> EXTRA ; ] * >>> +- if( dbg>0 ) log( "Start: " + pos + " " + end ); >>> +- +- pos=skipSpaces(bytes, pos, end); >>> +- if( pos>=end ) >>> +- return; // only spaces >>> +- int startName=pos; >>> +- if( dbg>0 ) log( "SN: " + pos ); >>> +- +- // Version should be the first token >>> +- boolean isSpecial=false; >>> +- if(bytes[pos]=='$') { pos++; isSpecial=true; } >>> +- >>> +- pos= findDelim1( bytes, startName, end); // " =;," >>> +- int endName=pos; >>> +- // current = "=" or " " or DELIM >>> +- pos= skipSpaces( bytes, endName, end ); +- >>> if( dbg>0 ) log( "DELIM: " + endName + " " + (char)bytes[pos]); >>> +- >>> +- if(pos >= end ) { >>> +- // it's a name-only cookie ( valid in RFC2109 ) >>> +- if( ! isSpecial ) { >>> +- sc=addCookie(); >>> +- sc.getName().setBytes( bytes, startName, >>> +- endName-startName ); >>> +- sc.getValue().setString(""); >>> +- sc.setVersion( version ); >>> +- if( dbg>0 ) log( "Name only, end: " + startName >>> + " " + >>> +- endName); >>> +- } >>> +- return; >>> +- } >>> +- >>> +- cc=bytes[pos]; >>> +- pos++; >>> +- if( cc==';' || cc==',' || pos>=end ) { >>> +- if( ! isSpecial && startName!= endName ) { >>> +- sc=addCookie(); >>> +- sc.getName().setBytes( bytes, startName, >>> +- endName-startName ); >>> +- sc.getValue().setString(""); >>> +- sc.setVersion( version ); >>> +- if( dbg>0 ) log( "Name only: " + startName + " >>> " + endName); >>> +- } >>> +- continue; >>> +- } >>> +- +- // we should have "=" ( tested all other >>> alternatives ) >>> +- int startValue=skipSpaces( bytes, pos, end); >>> +- int endValue=startValue; >>> +- +- cc=bytes[pos]; >>> +- if( cc=='"' ) { >>> +- endValue=findDelim3( bytes, startValue+1, end, cc ); >>> +- if (endValue == -1) { >>> +- endValue=findDelim2( bytes, startValue+1, end ); >>> +- } else startValue++; >>> +- pos=endValue+1; // to skip to next cookie >>> +- } else { >>> +- endValue=findDelim2( bytes, startValue, end ); >>> +- pos=endValue+1; >>> +- } >>> +- +- // if not $Version, etc >>> +- if( ! isSpecial ) { >>> +- sc=addCookie(); >>> +- sc.getName().setBytes( bytes, startName, >>> endName-startName ); >>> +- sc.getValue().setBytes( bytes, startValue, >>> endValue-startValue); >>> +- sc.setVersion( version ); >>> +- if( dbg>0 ) { >>> +- log( "New: " + sc.getName() + "X=X" + >>> sc.getValue()); >>> +- } >>> +- continue; >>> +- } >>> +- +- // special - Path, Version, Domain, Port >>> +- if( dbg>0 ) log( "Special: " + startName + " " + endName); >>> +- // XXX TODO >>> +- if( equals( "$Version", bytes, startName, endName ) ) { >>> +- if(dbg>0 ) log( "Found version " ); >>> +- if( bytes[startValue]=='1' && >>> endValue==startValue+1 ) { >>> +- version=1; >>> +- if(dbg>0 ) log( "Found version=1" ); >>> +- } >>> +- continue; >>> +- } >>> +- if( sc==null ) { >>> +- // Path, etc without a previous cookie >>> +- continue; >>> +- } >>> +- if( equals( "$Path", bytes, startName, endName ) ) { >>> +- sc.getPath().setBytes( bytes, >>> +- startValue, >>> +- endValue-startValue ); >>> +- } >>> +- if( equals( "$Domain", bytes, startName, endName ) ) { >>> +- sc.getDomain().setBytes( bytes, >>> +- startValue, >>> +- endValue-startValue ); >>> +- } >>> +- if( equals( "$Port", bytes, startName, endName ) ) { >>> +- // sc.getPort().setBytes( bytes, >>> +- // startValue, >>> +- // endValue-startValue ); >>> +- } >>> +- } >>> +- } >>> +- >>> +- // -------------------- Utils -------------------- >>> +- public static int skipSpaces( byte bytes[], int off, int end ) { >>> +- while( off < end ) { >>> +- byte b=bytes[off]; >>> +- if( b!= ' ' ) return off; >>> +- off ++; >>> +- } >>> +- return off; >>> +- } >>> +- >>> +- public static int findDelim1( byte bytes[], int off, int end ) >>> +- { >>> +- while( off < end ) { >>> +- byte b=bytes[off]; >>> +- if( b==' ' || b=='=' || b==';' || b==',' ) >>> +- return off; >>> +- off++; >>> +- } >>> +- return off; >>> +- } >>> +- >>> +- public static int findDelim2( byte bytes[], int off, int end ) >>> +- { >>> +- while( off < end ) { >>> +- byte b=bytes[off]; >>> +- if( b==';' || b==',' ) >>> +- return off; >>> +- off++; >>> +- } >>> +- return off; >>> +- } >>> +- >>> +- /* >>> +- * search for cc but skip \cc as required by rfc2616 >>> +- * (according to rfc2616 cc should be ") >>> +- */ >>> +- public static int findDelim3( byte bytes[], int off, int end, >>> byte cc ) >>> +- { >>> +- while( off < end ) { >>> +- byte b=bytes[off]; >>> +- if ( b== '\\' ) { >>> +- off++; >>> +- off++; >>> +- continue; >>> +- } >>> +- if( b==cc ) >>> +- return off; >>> +- off++; >>> +- } >>> +- return -1; >>> +- } >>> +- >>> + // XXX will be refactored soon! >>> + public static boolean equals( String s, byte b[], int start, >>> int end) { >>> + int blen = end-start; >>> +@@ -440,42 +286,294 @@ >>> + log.debug("Cookies: " + s); >>> + } >>> + +- /* >>> +- public static void main( String args[] ) { >>> +- test("foo=bar; a=b"); >>> +- test("foo=bar;a=b"); >>> +- test("foo=bar;a=b;"); >>> +- test("foo=bar;a=b; "); >>> +- test("foo=bar;a=b; ;"); >>> +- test("foo=;a=b; ;"); >>> +- test("foo;a=b; ;"); >>> +- // v1 +- test("$Version=1; foo=bar;a=b"); +- >>> test("$Version=\"1\"; foo='bar'; $Path=/path; $Domain=\"localhost\""); >>> +- test("$Version=1;foo=bar;a=b; ; "); >>> +- test("$Version=1;foo=;a=b; ; "); >>> +- test("$Version=1;foo= ;a=b; ; "); >>> +- test("$Version=1;foo;a=b; ; "); >>> +- test("$Version=1;foo=\"bar\";a=b; ; "); >>> +- test("$Version=1;foo=\"bar\";$Path=/examples;a=b; ; "); >>> +- test("$Version=1;foo=\"bar\";$Domain=apache.org;a=b"); >>> +- >>> test("$Version=1;foo=\"bar\";$Domain=apache.org;a=b;$Domain=yahoo.com"); >>> +- // rfc2965 >>> +- >>> test("$Version=1;foo=\"bar\";$Domain=apache.org;$Port=8080;a=b"); >>> ++ >>> ++ /** >>> ++ * Returns true if the byte is a separator character as >>> ++ * defined in RFC2619. Since this is called often, this >>> ++ * function should be organized with the most probable >>> ++ * outcomes first. >>> ++ * JVK >>> ++ */ >>> ++ public static final boolean isSeparator(final byte c) { >>> ++ if (c > 0 && c < 126) >>> ++ return separators[c]; >>> ++ else >>> ++ return false; >>> ++ } >>> ++ ++ /** >>> ++ * Returns true if the byte is a whitespace character as >>> ++ * defined in RFC2619 >>> ++ * JVK >>> ++ */ >>> ++ public static final boolean isWhiteSpace(final byte c) { >>> ++ // This switch statement is slightly slower >>> ++ // for my vm than the if statement. >>> ++ // Java(TM) 2 Runtime Environment, Standard Edition (build >>> 1.5.0_07-164) >>> ++ /* ++ switch (c) { >>> ++ case ' ':; >>> ++ case '\t':; >>> ++ case '\n':; >>> ++ case '\r':; >>> ++ case '\f':; >>> ++ return true; >>> ++ default:; >>> ++ return false; >>> ++ } >>> ++ */ >>> ++ if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == >>> '\f') >>> ++ return true; >>> ++ else >>> ++ return false; >>> ++ } >>> ++ >>> ++ /** >>> ++ * Parses a cookie header after the initial "Cookie:" >>> ++ * [WS][$]token[WS]=[WS](token|QV)[;|,] >>> ++ * RFC 2965 >>> ++ * JVK >>> ++ */ >>> ++ public final void processCookieHeader(byte bytes[], int off, >>> int len){ >>> ++ if( len<=0 || bytes==null ) return; >>> ++ int end=off+len; >>> ++ int pos=off; >>> ++ int nameStart=0; >>> ++ int nameEnd=0; >>> ++ int valueStart=0; >>> ++ int valueEnd=0; >>> ++ int version = 0; >>> ++ ServerCookie sc=null; >>> ++ boolean isSpecial; >>> ++ >>> ++ while (pos < end) { >>> ++ isSpecial = false; >>> ++ >>> ++ // Skip whitespace and non-token characters (separators) >>> ++ while (pos < end && ++ >>> (isSeparator(bytes[pos]) || isWhiteSpace(bytes[pos]))) >>> ++ {pos++; } ++ >>> ++ if (pos >= end) >>> ++ return; >>> ++ >>> ++ // Detect Special cookies >>> ++ if (bytes[pos] == '$') { >>> ++ isSpecial = true; >>> ++ pos++; >>> ++ } >>> ++ >>> ++ // Get the cookie name. This must be a token >>> ++ valueEnd = valueStart = nameStart = pos; ++ >>> pos = nameEnd = getTokenEndPosition(bytes,pos,end); >>> ++ >>> ++ // Skip whitespace >>> ++ while (pos < end && isWhiteSpace(bytes[pos])) {pos++; >>> }; ++ ++ >>> ++ // Check for an '=' -- This could also be a name-only >>> ++ // cookie at the end of the cookie header, so if we >>> ++ // are past the end of the header, but we have a name >>> ++ // skip to the name-only part. >>> ++ if (pos < end && bytes[pos] == '=') { ++ >>> ++ // Skip whitespace >>> ++ do { >>> ++ pos++; >>> ++ } while (pos < end && isWhiteSpace(bytes[pos])); ++ >>> ++ if (pos >= end) >>> ++ return; >>> ++ >>> ++ // Determine what type of value this is, quoted value, >>> ++ // token, name-only with an '=', or other (bad) >>> ++ switch (bytes[pos]) { >>> ++ case '"':; // Quoted Value >>> ++ valueStart=pos + 1; // strip " >>> ++ // getQuotedValue returns the position before >>> ++ // at the last qoute. This must be dealt with >>> ++ // when the bytes are copied into the cookie >>> ++ valueEnd=getQuotedValueEndPosition(bytes, >>> ++ valueStart, >>> end); >>> ++ // We need pos to advance >>> ++ pos = valueEnd; ++ // >>> Handles cases where the quoted value is ++ // >>> unterminated and at the end of the header, ++ // >>> e.g. [myname="value] >>> ++ if (pos >= end) >>> ++ return; >>> ++ break; >>> ++ case ';': >>> ++ case ',': >>> ++ // Name-only cookie with an '=' after the name >>> token >>> ++ // This may not be RFC compliant >>> ++ valueStart = valueEnd = -1; >>> ++ // The position is OK (On a delimiter) >>> ++ break; >>> ++ default:; >>> ++ if (!isSeparator(bytes[pos])) { >>> ++ // Token >>> ++ valueStart=pos; >>> ++ // getToken returns the position at the >>> delimeter >>> ++ // or other non-token character >>> ++ valueEnd=getTokenEndPosition(bytes, >>> valueStart, end); >>> ++ // We need pos to advance >>> ++ pos = valueEnd; >>> ++ } else { >>> ++ // INVALID COOKIE, advance to next delimiter >>> ++ // The starting character of the cookie >>> value was >>> ++ // not valid. >>> ++ log("Invalid cookie. Value not a token or >>> quoted value"); >>> ++ while (pos < end && bytes[pos] != ';' && >>> ++ bytes[pos] != ',') >>> ++ {pos++; }; >>> ++ pos++; >>> ++ // Make sure no special avpairs can be >>> attributed to ++ // the previous cookie by >>> setting the current cookie >>> ++ // to null >>> ++ sc = null; >>> ++ continue; >>> ++ } >>> ++ } >>> ++ } else { >>> ++ // Name only cookie >>> ++ valueStart = valueEnd = -1; >>> ++ pos = nameEnd; >>> ++ >>> ++ } >>> ++ ++ // We should have an avpair or name-only >>> cookie at this >>> ++ // point. Perform some basic checks to make sure we are >>> ++ // in a good state. >>> ++ ++ // Skip whitespace >>> ++ while (pos < end && isWhiteSpace(bytes[pos])) {pos++; >>> }; ++ >>> ++ >>> ++ // Make sure that after the cookie we have a separator. >>> This >>> ++ // is only important if this is not the last cookie pair >>> ++ while (pos < end && bytes[pos] != ';' && bytes[pos] != >>> ',') { ++ pos++; >>> ++ } >>> ++ ++ pos++; >>> ++ >>> ++ /* >>> ++ if (nameEnd <= nameStart || valueEnd < valueStart ) { >>> ++ // Something is wrong, but this may be a case >>> ++ // of having two ';' characters in a row. >>> ++ // log("Cookie name/value does not conform to RFC >>> 2965"); >>> ++ // Advance to next delimiter (ignoring everything >>> else) >>> ++ while (pos < end && bytes[pos] != ';' && bytes[pos] >>> != ',') ++ { pos++; }; >>> ++ pos++; >>> ++ // Make sure no special cookies can be attributed >>> to ++ // the previous cookie by setting the current >>> cookie >>> ++ // to null >>> ++ sc = null; >>> ++ continue; >>> ++ } >>> ++ */ >>> ++ >>> ++ // All checks passed. Add the cookie, start with the >>> ++ // special avpairs first >>> ++ if (isSpecial) { >>> ++ isSpecial = false; >>> ++ // $Version must be the first avpair in the cookie >>> header >>> ++ // (sc must be null) >>> ++ if (equals( "Version", bytes, nameStart, nameEnd) >>> && ++ sc == null) { >>> ++ // Set version >>> ++ if( bytes[valueStart] =='1' && valueEnd == >>> valueStart) { >>> ++ version=1; >>> ++ } else { >>> ++ // unknown version (Versioning is not very >>> strict) >>> ++ } >>> ++ continue; >>> ++ } ++ ++ // We need an >>> active cookie for Path/Port/etc. >>> ++ if (sc == null) { >>> ++ continue; >>> ++ } >>> ++ >>> ++ // Domain is more common, so it goes first >>> ++ if (equals( "Domain", bytes, nameStart, nameEnd)) { >>> ++ sc.getDomain().setBytes( bytes, >>> ++ valueStart, >>> ++ valueEnd-valueStart); >>> ++ continue; >>> ++ } ++ >>> ++ if (equals( "Path", bytes, nameStart, nameEnd)) { >>> ++ sc.getPath().setBytes( bytes, >>> ++ valueStart, >>> ++ valueEnd-valueStart); >>> ++ continue; >>> ++ } ++ >>> ++ >>> ++ if (equals( "Port", bytes, nameStart, nameEnd)) { >>> ++ // sc.getPort is not currently implemented. >>> ++ // sc.getPort().setBytes( bytes, >>> ++ // valueStart, >>> ++ // valueEnd-valueStart ); >>> ++ continue; >>> ++ } ++ >>> ++ // Unknown cookie, complain >>> ++ log("Unknown Special Cookie"); >>> + +- // wrong >>> +- >>> test("$Version=1;foo=\"bar\";$Domain=apache.org;$Port=8080;a=b"); >>> ++ } else { // Normal Cookie >>> ++ sc = addCookie(); >>> ++ sc.setVersion( version ); >>> ++ sc.getName().setBytes( bytes, nameStart, >>> ++ nameEnd-nameStart); >>> ++ ++ if (valueStart != -1) { // Normal >>> AVPair >>> ++ sc.getValue().setBytes( bytes, valueStart, >>> ++ valueEnd-valueStart); >>> ++ } else { >>> ++ // Name Only >>> ++ sc.getValue().setString(""); ++ } >>> ++ continue; >>> ++ } >>> ++ } >>> + } >>> + +- public static void test( String s ) { >>> +- System.out.println("Processing " + s ); >>> +- Cookies cs=new Cookies(null); >>> +- cs.processCookieHeader( s.getBytes(), 0, s.length()); >>> +- for( int i=0; i< cs.getCookieCount() ; i++ ) { >>> +- System.out.println("Cookie: " + cs.getCookie( i )); >>> ++ /** >>> ++ * Given the starting position of a token, this gets the end of >>> the >>> ++ * token, with no separator characters in between. >>> ++ * JVK >>> ++ */ >>> ++ public static final int getTokenEndPosition(byte bytes[], int >>> off, int end){ >>> ++ int pos = off; >>> ++ while (pos < end && !isSeparator(bytes[pos])) {pos++; }; >>> ++ ++ if (pos > end) >>> ++ return end; >>> ++ return pos; >>> ++ } >>> ++ >>> ++ /** ++ * Given a starting position after an initial quote >>> chracter, this gets >>> ++ * the position of the end quote. This escapes anything after a >>> '\' char >>> ++ * JVK RFC 2616 >>> ++ */ >>> ++ public static final int getQuotedValueEndPosition(byte bytes[], >>> int off, int end){ >>> ++ int pos = off; >>> ++ while (pos < end) { >>> ++ if (bytes[pos] == '"') { >>> ++ return pos; ++ } else if >>> (bytes[pos] == '\\' && pos < (end - 1)) { >>> ++ pos+=2; >>> ++ } else { >>> ++ pos++; >>> ++ } >>> + } >>> +- ++ // Error, we have reached the end of the >>> header w/o a end quote >>> ++ return end; >>> + } >>> +- */ >>> + + } >>> + >>> >>> >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: [EMAIL PROTECTED] >>> For additional commands, e-mail: [EMAIL PROTECTED] >>> >>> >>> >>> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> For additional commands, e-mail: [EMAIL PROTECTED] >> >> >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]