Changeset 996

Show
Ignore:
Timestamp:
03/27/08 16:46:28 (5 months ago)
Author:
normalperson
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ext/http11/http11_parser.c

    r990 r996  
    485485        switch( (*p) ) { 
    486486                case 32: goto tr30; 
     487                case 35: goto st0; 
    487488                case 37: goto tr31; 
    488                 case 60: goto st0; 
    489                 case 62: goto st0; 
    490489                case 127: goto st0; 
    491490        } 
    492         if ( (*p) > 31 ) { 
    493                 if ( 34 <= (*p) && (*p) <= 35 ) 
    494                         goto st0; 
    495         } else if ( (*p) >= 0 ) 
     491        if ( 0 <= (*p) && (*p) <= 31 ) 
    496492                goto st0; 
    497493        goto tr29; 
     
    504500                goto _out21; 
    505501case 21: 
    506 #line 507 "http11_parser.c" 
     502#line 503 "http11_parser.c" 
    507503        switch( (*p) ) { 
    508504                case 32: goto tr30; 
     505                case 35: goto st0; 
    509506                case 37: goto st22; 
    510                 case 60: goto st0; 
    511                 case 62: goto st0; 
    512507                case 127: goto st0; 
    513508        } 
    514         if ( (*p) > 31 ) { 
    515                 if ( 34 <= (*p) && (*p) <= 35 ) 
    516                         goto st0; 
    517         } else if ( (*p) >= 0 ) 
     509        if ( 0 <= (*p) && (*p) <= 31 ) 
    518510                goto st0; 
    519511        goto st21; 
     
    526518                goto _out22; 
    527519case 22: 
    528 #line 529 "http11_parser.c" 
     520#line 521 "http11_parser.c" 
    529521        if ( (*p) < 65 ) { 
    530522                if ( 48 <= (*p) && (*p) <= 57 ) 
     
    557549                goto _out24; 
    558550case 24: 
    559 #line 560 "http11_parser.c" 
     551#line 552 "http11_parser.c" 
    560552        switch( (*p) ) { 
    561553                case 43: goto st24; 
     
    582574                goto _out25; 
    583575case 25: 
    584 #line 585 "http11_parser.c" 
     576#line 577 "http11_parser.c" 
    585577        switch( (*p) ) { 
    586578                case 32: goto tr8; 
    587                 case 34: goto st0; 
    588579                case 35: goto tr9; 
    589580                case 37: goto st26; 
    590                 case 60: goto st0; 
    591                 case 62: goto st0; 
    592581                case 127: goto st0; 
    593582        } 
     
    629618                goto _out28; 
    630619case 28: 
    631 #line 632 "http11_parser.c" 
     620#line 621 "http11_parser.c" 
    632621        switch( (*p) ) { 
    633622                case 32: goto tr40; 
    634                 case 34: goto st0; 
    635623                case 35: goto tr41; 
    636624                case 37: goto st29; 
    637625                case 59: goto tr43; 
    638                 case 60: goto st0; 
    639                 case 62: goto st0; 
    640626                case 63: goto tr44; 
    641627                case 127: goto st0; 
     
    681667                goto _out31; 
    682668case 31: 
    683 #line 684 "http11_parser.c" 
     669#line 670 "http11_parser.c" 
    684670        switch( (*p) ) { 
    685671                case 32: goto tr8; 
    686                 case 34: goto st0; 
    687672                case 35: goto tr9; 
    688673                case 37: goto st32; 
    689                 case 60: goto st0; 
    690                 case 62: goto st0; 
    691674                case 63: goto st34; 
    692675                case 127: goto st0; 
     
    732715                goto _out34; 
    733716case 34: 
    734 #line 735 "http11_parser.c" 
     717#line 718 "http11_parser.c" 
    735718        switch( (*p) ) { 
    736719                case 32: goto tr51; 
    737                 case 34: goto st0; 
    738720                case 35: goto tr52; 
    739721                case 37: goto tr53; 
    740                 case 60: goto st0; 
    741                 case 62: goto st0; 
    742722                case 127: goto st0; 
    743723        } 
     
    753733                goto _out35; 
    754734case 35: 
    755 #line 756 "http11_parser.c" 
     735#line 736 "http11_parser.c" 
    756736        switch( (*p) ) { 
    757737                case 32: goto tr55; 
    758                 case 34: goto st0; 
    759738                case 35: goto tr56; 
    760739                case 37: goto st36; 
    761                 case 60: goto st0; 
    762                 case 62: goto st0; 
    763740                case 127: goto st0; 
    764741        } 
     
    774751                goto _out36; 
    775752case 36: 
    776 #line 777 "http11_parser.c" 
     753#line 754 "http11_parser.c" 
    777754        if ( (*p) < 65 ) { 
    778755                if ( 48 <= (*p) && (*p) <= 57 ) 
     
    12041181    /* final \r\n combo encountered so stop right here */ 
    12051182     
    1206 #line 1207 "http11_parser.c" 
     1183#line 1184 "http11_parser.c" 
    12071184#line 136 "http11_parser.rl" 
    12081185    parser->nread++; 
     
    12171194 
    12181195   
    1219 #line 1220 "http11_parser.c" 
     1196#line 1197 "http11_parser.c" 
    12201197#line 147 "http11_parser.rl" 
    12211198 
  • trunk/ext/http11/http11_parser_common.rl

    r990 r996  
    1212  extra = ("!" | "*" | "'" | "(" | ")" | ","); 
    1313  reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"); 
    14   unsafe = (CTL | " " | "\"" | "#" | "%" | "<" | ">"); 
     14  sorta_safe = ("\"" | "<" | ">"); 
     15  unsafe = (CTL | " " | "#" | "%" | sorta_safe); 
    1516  national = any -- (alpha | digit | reserved | extra | safe | unsafe); 
    1617  unreserved = (alpha | digit | safe | extra | national); 
    1718  escape = ("%" xdigit xdigit); 
    18   uchar = (unreserved | escape); 
     19  uchar = (unreserved | escape | sorta_safe); 
    1920  pchar = (uchar | ":" | "@" | "&" | "=" | "+"); 
    2021  tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t"); 
  • trunk/test/test_http11.rb

    r993 r996  
    5353    #assert !parser.error? 
    5454  end 
     55 
     56  def test_parse_ie6_urls 
     57    %w(/some/random/path" 
     58       /some/random/path> 
     59       /some/random/path< 
     60       /we/love/you/ie6?q=<""> 
     61       /url?<="&>=" 
     62       /mal"formed"? 
     63    ).each do |path| 
     64      parser = HttpParser.new 
     65      req = {} 
     66      sorta_safe = %(GET #{path} HTTP/1.1\r\n\r\n) 
     67      nread = parser.execute(req, sorta_safe, 0) 
     68      assert_equal sorta_safe.length, nread 
     69      assert parser.finished? 
     70      assert !parser.error? 
     71    end 
     72  end 
    5573   
    5674  def test_parse_error