Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

http11_parser: accept '"' (double-quote), '<', and '>' characters in …

…URLs

Some broken web browsers don't properly escape ", <, and > characters
in URLs, however these URLs to occasionally legitimate and sometimes
show up.

This patch was submitted by Eden Li here:
  http://rubyforge.org/pipermail/mongrel-users/2006-October/001845.html

This patch was accepted by Zed Shaw here:
  http://rubyforge.org/pipermail/mongrel-users/2006-October/001847.html


git-svn-id: svn://rubyforge.org/var/svn/mongrel/trunk@996 19e92222-5c0b-0410-8929-a290d50e31e9
  • Loading branch information...
commit 04dfa3356f9721d344c83816c0ac7e0fa9638f15 1 parent 1878608
normalperson authored
View
53 ext/http11/http11_parser.c
@@ -484,15 +484,11 @@ case 20:
#line 485 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr30;
+ case 35: goto st0;
case 37: goto tr31;
- case 60: goto st0;
- case 62: goto st0;
case 127: goto st0;
}
- if ( (*p) > 31 ) {
- if ( 34 <= (*p) && (*p) <= 35 )
- goto st0;
- } else if ( (*p) >= 0 )
+ if ( 0 <= (*p) && (*p) <= 31 )
goto st0;
goto tr29;
tr29:
@@ -503,18 +499,14 @@ case 20:
if ( ++p == pe )
goto _out21;
case 21:
-#line 507 "http11_parser.c"
+#line 503 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr30;
+ case 35: goto st0;
case 37: goto st22;
- case 60: goto st0;
- case 62: goto st0;
case 127: goto st0;
}
- if ( (*p) > 31 ) {
- if ( 34 <= (*p) && (*p) <= 35 )
- goto st0;
- } else if ( (*p) >= 0 )
+ if ( 0 <= (*p) && (*p) <= 31 )
goto st0;
goto st21;
tr31:
@@ -525,7 +517,7 @@ case 21:
if ( ++p == pe )
goto _out22;
case 22:
-#line 529 "http11_parser.c"
+#line 521 "http11_parser.c"
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
goto st23;
@@ -556,7 +548,7 @@ case 23:
if ( ++p == pe )
goto _out24;
case 24:
-#line 560 "http11_parser.c"
+#line 552 "http11_parser.c"
switch( (*p) ) {
case 43: goto st24;
case 58: goto st25;
@@ -581,14 +573,11 @@ case 24:
if ( ++p == pe )
goto _out25;
case 25:
-#line 585 "http11_parser.c"
+#line 577 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr8;
- case 34: goto st0;
case 35: goto tr9;
case 37: goto st26;
- case 60: goto st0;
- case 62: goto st0;
case 127: goto st0;
}
if ( 0 <= (*p) && (*p) <= 31 )
@@ -628,15 +617,12 @@ case 27:
if ( ++p == pe )
goto _out28;
case 28:
-#line 632 "http11_parser.c"
+#line 621 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr40;
- case 34: goto st0;
case 35: goto tr41;
case 37: goto st29;
case 59: goto tr43;
- case 60: goto st0;
- case 62: goto st0;
case 63: goto tr44;
case 127: goto st0;
}
@@ -680,14 +666,11 @@ case 30:
if ( ++p == pe )
goto _out31;
case 31:
-#line 684 "http11_parser.c"
+#line 670 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr8;
- case 34: goto st0;
case 35: goto tr9;
case 37: goto st32;
- case 60: goto st0;
- case 62: goto st0;
case 63: goto st34;
case 127: goto st0;
}
@@ -731,14 +714,11 @@ case 33:
if ( ++p == pe )
goto _out34;
case 34:
-#line 735 "http11_parser.c"
+#line 718 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr51;
- case 34: goto st0;
case 35: goto tr52;
case 37: goto tr53;
- case 60: goto st0;
- case 62: goto st0;
case 127: goto st0;
}
if ( 0 <= (*p) && (*p) <= 31 )
@@ -752,14 +732,11 @@ case 34:
if ( ++p == pe )
goto _out35;
case 35:
-#line 756 "http11_parser.c"
+#line 736 "http11_parser.c"
switch( (*p) ) {
case 32: goto tr55;
- case 34: goto st0;
case 35: goto tr56;
case 37: goto st36;
- case 60: goto st0;
- case 62: goto st0;
case 127: goto st0;
}
if ( 0 <= (*p) && (*p) <= 31 )
@@ -773,7 +750,7 @@ case 35:
if ( ++p == pe )
goto _out36;
case 36:
-#line 777 "http11_parser.c"
+#line 754 "http11_parser.c"
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
goto st37;
@@ -1203,7 +1180,7 @@ case 56:
if(parser->body_start) {
/* final \r\n combo encountered so stop right here */
-#line 1207 "http11_parser.c"
+#line 1184 "http11_parser.c"
#line 136 "http11_parser.rl"
parser->nread++;
}
@@ -1216,7 +1193,7 @@ int http_parser_finish(http_parser *parser)
int cs = parser->cs;
-#line 1220 "http11_parser.c"
+#line 1197 "http11_parser.c"
#line 147 "http11_parser.rl"
parser->cs = cs;
View
5 ext/http11/http11_parser_common.rl
@@ -11,11 +11,12 @@
safe = ("$" | "-" | "_" | ".");
extra = ("!" | "*" | "'" | "(" | ")" | ",");
reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+");
- unsafe = (CTL | " " | "\"" | "#" | "%" | "<" | ">");
+ sorta_safe = ("\"" | "<" | ">");
+ unsafe = (CTL | " " | "#" | "%" | sorta_safe);
national = any -- (alpha | digit | reserved | extra | safe | unsafe);
unreserved = (alpha | digit | safe | extra | national);
escape = ("%" xdigit xdigit);
- uchar = (unreserved | escape);
+ uchar = (unreserved | escape | sorta_safe);
pchar = (uchar | ":" | "@" | "&" | "=" | "+");
tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
View
18 test/test_http11.rb
@@ -52,6 +52,24 @@ def test_parse_dumbfuck_headers
#assert parser.finished?
#assert !parser.error?
end
+
+ def test_parse_ie6_urls
+ %w(/some/random/path"
+ /some/random/path>
+ /some/random/path<
+ /we/love/you/ie6?q=<"">
+ /url?<="&>="
+ /mal"formed"?
+ ).each do |path|
+ parser = HttpParser.new
+ req = {}
+ sorta_safe = %(GET #{path} HTTP/1.1\r\n\r\n)
+ nread = parser.execute(req, sorta_safe, 0)
+ assert_equal sorta_safe.length, nread
+ assert parser.finished?
+ assert !parser.error?
+ end
+ end
def test_parse_error
parser = HttpParser.new
Please sign in to comment.
Something went wrong with that request. Please try again.