Fossil SCM
Ignore obsolete folded chunked http headers, and multiple chunk request. From libfossil.
Commit
c272f25079a5dbd0f9e7f929f73c3ef24a9f012e07bb47883added886f87cab8
Parent
99546127422fb2d…
1 file changed
+13
+13
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -600,10 +600,18 @@ | ||
| 600 | 600 | iLength = -1; |
| 601 | 601 | iHttpVersion = -1; |
| 602 | 602 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 603 | 603 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 604 | 604 | fossil_print("Read: [%s]\n", zLine); |
| 605 | + } | |
| 606 | + if( zLine[0]==' ' || zLine[0]=='\t' ){ | |
| 607 | + /* A line starting with a space or tab continues the previous | |
| 608 | + ** header (obsolete line folding, RFC 9112 section 5.2) and in this | |
| 609 | + ** case we disregard the RFC because it gets messy. This is what | |
| 610 | + ** the llhttp project and others do. */ | |
| 611 | + fossil_warning("server sent a folded header line"); | |
| 612 | + goto write_err; | |
| 605 | 613 | } |
| 606 | 614 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 607 | 615 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 608 | 616 | if( rc/100==1 ){ |
| 609 | 617 | /* Parse and discard an unexpected 1xx interim reply, most commonly |
| @@ -685,10 +693,15 @@ | ||
| 685 | 693 | } |
| 686 | 694 | if( !bOk ){ |
| 687 | 695 | fossil_warning("unsupported transfer-encoding: %s", &zLine[18]); |
| 688 | 696 | goto write_err; |
| 689 | 697 | } |
| 698 | + if( isChunked ){ | |
| 699 | + /* (RFC 9110 section 5.3), chunked may be applied only once */ | |
| 700 | + fossil_warning("server sent two transfer-encoding headers"); | |
| 701 | + goto write_err; | |
| 702 | + } | |
| 690 | 703 | isChunked = 1; |
| 691 | 704 | }else if( fossil_strnicmp(zLine, "connection:", 11)==0 ){ |
| 692 | 705 | if( sqlite3_strlike("%close%", &zLine[11], 0)==0 ){ |
| 693 | 706 | closeConnection = 1; |
| 694 | 707 | }else if( sqlite3_strlike("%keep-alive%", &zLine[11], 0)==0 ){ |
| 695 | 708 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -600,10 +600,18 @@ | |
| 600 | iLength = -1; |
| 601 | iHttpVersion = -1; |
| 602 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 603 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 604 | fossil_print("Read: [%s]\n", zLine); |
| 605 | } |
| 606 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 607 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 608 | if( rc/100==1 ){ |
| 609 | /* Parse and discard an unexpected 1xx interim reply, most commonly |
| @@ -685,10 +693,15 @@ | |
| 685 | } |
| 686 | if( !bOk ){ |
| 687 | fossil_warning("unsupported transfer-encoding: %s", &zLine[18]); |
| 688 | goto write_err; |
| 689 | } |
| 690 | isChunked = 1; |
| 691 | }else if( fossil_strnicmp(zLine, "connection:", 11)==0 ){ |
| 692 | if( sqlite3_strlike("%close%", &zLine[11], 0)==0 ){ |
| 693 | closeConnection = 1; |
| 694 | }else if( sqlite3_strlike("%keep-alive%", &zLine[11], 0)==0 ){ |
| 695 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -600,10 +600,18 @@ | |
| 600 | iLength = -1; |
| 601 | iHttpVersion = -1; |
| 602 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 603 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 604 | fossil_print("Read: [%s]\n", zLine); |
| 605 | } |
| 606 | if( zLine[0]==' ' || zLine[0]=='\t' ){ |
| 607 | /* A line starting with a space or tab continues the previous |
| 608 | ** header (obsolete line folding, RFC 9112 section 5.2) and in this |
| 609 | ** case we disregard the RFC because it gets messy. This is what |
| 610 | ** the llhttp project and others do. */ |
| 611 | fossil_warning("server sent a folded header line"); |
| 612 | goto write_err; |
| 613 | } |
| 614 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 615 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 616 | if( rc/100==1 ){ |
| 617 | /* Parse and discard an unexpected 1xx interim reply, most commonly |
| @@ -685,10 +693,15 @@ | |
| 693 | } |
| 694 | if( !bOk ){ |
| 695 | fossil_warning("unsupported transfer-encoding: %s", &zLine[18]); |
| 696 | goto write_err; |
| 697 | } |
| 698 | if( isChunked ){ |
| 699 | /* (RFC 9110 section 5.3), chunked may be applied only once */ |
| 700 | fossil_warning("server sent two transfer-encoding headers"); |
| 701 | goto write_err; |
| 702 | } |
| 703 | isChunked = 1; |
| 704 | }else if( fossil_strnicmp(zLine, "connection:", 11)==0 ){ |
| 705 | if( sqlite3_strlike("%close%", &zLine[11], 0)==0 ){ |
| 706 | closeConnection = 1; |
| 707 | }else if( sqlite3_strlike("%keep-alive%", &zLine[11], 0)==0 ){ |
| 708 |