Skip to content

Commit

Permalink
Port mongrel r996 parser fix to accept some weird ie6 headers:
Browse files Browse the repository at this point in the history
  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
  • Loading branch information
macournoyer committed Apr 3, 2008
1 parent dfb9dde commit 9ae43ca
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 40 deletions.
5 changes: 3 additions & 2 deletions ext/thin_parser/common.rl
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
53 changes: 15 additions & 38 deletions ext/thin_parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,15 +484,11 @@ case 20:
#line 485 "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:
Expand All @@ -503,18 +499,14 @@ case 20:
if ( ++p == pe )
goto _out21;
case 21:
#line 507 "parser.c"
#line 503 "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:
Expand All @@ -525,7 +517,7 @@ case 21:
if ( ++p == pe )
goto _out22;
case 22:
#line 529 "parser.c"
#line 521 "parser.c"
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
goto st23;
Expand Down Expand Up @@ -556,7 +548,7 @@ case 23:
if ( ++p == pe )
goto _out24;
case 24:
#line 560 "parser.c"
#line 552 "parser.c"
switch( (*p) ) {
case 43: goto st24;
case 58: goto st25;
Expand All @@ -581,14 +573,11 @@ case 24:
if ( ++p == pe )
goto _out25;
case 25:
#line 585 "parser.c"
#line 577 "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 )
Expand Down Expand Up @@ -628,15 +617,12 @@ case 27:
if ( ++p == pe )
goto _out28;
case 28:
#line 632 "parser.c"
#line 621 "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;
}
Expand Down Expand Up @@ -681,14 +667,11 @@ case 30:
if ( ++p == pe )
goto _out31;
case 31:
#line 685 "parser.c"
#line 671 "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;
}
Expand Down Expand Up @@ -733,14 +716,11 @@ case 33:
if ( ++p == pe )
goto _out34;
case 34:
#line 737 "parser.c"
#line 720 "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 )
Expand All @@ -754,14 +734,11 @@ case 34:
if ( ++p == pe )
goto _out35;
case 35:
#line 758 "parser.c"
#line 738 "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 )
Expand All @@ -775,7 +752,7 @@ case 35:
if ( ++p == pe )
goto _out36;
case 36:
#line 779 "parser.c"
#line 756 "parser.c"
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
goto st37;
Expand Down Expand Up @@ -1205,7 +1182,7 @@ case 56:
if(parser->body_start) {
/* final \r\n combo encountered so stop right here */

#line 1209 "parser.c"
#line 1186 "parser.c"
#line 130 "parser.rl"
parser->nread++;
}
Expand All @@ -1218,7 +1195,7 @@ int http_parser_finish(http_parser *parser)
int cs = parser->cs;


#line 1222 "parser.c"
#line 1199 "parser.c"
#line 141 "parser.rl"

parser->cs = cs;
Expand Down
18 changes: 18 additions & 0 deletions spec/request/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,22 @@
request.body.read.should == 'aye'
end

it "should parse ie6 urls" do
%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)

sorta_safe.size.should == nread
parser.should be_finished
parser.should_not have_error
end
end
end

0 comments on commit 9ae43ca

Please sign in to comment.