@@ -653,6 +653,8 @@ size_t http_parser_execute (http_parser *parser,
653
653
const char * status_mark = 0 ;
654
654
enum state p_state = (enum state ) parser -> state ;
655
655
const unsigned int lenient = parser -> lenient_http_headers ;
656
+ const unsigned int allow_chunked_length = parser -> allow_chunked_length ;
657
+
656
658
uint32_t nread = parser -> nread ;
657
659
658
660
/* We're in an error state. Don't bother doing anything. */
@@ -731,7 +733,7 @@ size_t http_parser_execute (http_parser *parser,
731
733
if (ch == CR || ch == LF )
732
734
break ;
733
735
parser -> flags = 0 ;
734
- parser -> extra_flags = 0 ;
736
+ parser -> uses_transfer_encoding = 0 ;
735
737
parser -> content_length = ULLONG_MAX ;
736
738
737
739
if (ch == 'H' ) {
@@ -769,7 +771,7 @@ size_t http_parser_execute (http_parser *parser,
769
771
if (ch == CR || ch == LF )
770
772
break ;
771
773
parser -> flags = 0 ;
772
- parser -> extra_flags = 0 ;
774
+ parser -> uses_transfer_encoding = 0 ;
773
775
parser -> content_length = ULLONG_MAX ;
774
776
775
777
if (ch == 'H' ) {
@@ -927,7 +929,7 @@ size_t http_parser_execute (http_parser *parser,
927
929
if (ch == CR || ch == LF )
928
930
break ;
929
931
parser -> flags = 0 ;
930
- parser -> extra_flags = 0 ;
932
+ parser -> uses_transfer_encoding = 0 ;
931
933
parser -> content_length = ULLONG_MAX ;
932
934
933
935
if (UNLIKELY (!IS_ALPHA (ch ))) {
@@ -1341,7 +1343,7 @@ size_t http_parser_execute (http_parser *parser,
1341
1343
parser -> header_state = h_general ;
1342
1344
} else if (parser -> index == sizeof (TRANSFER_ENCODING )- 2 ) {
1343
1345
parser -> header_state = h_transfer_encoding ;
1344
- parser -> extra_flags |= F_TRANSFER_ENCODING >> 8 ;
1346
+ parser -> uses_transfer_encoding = 1 ;
1345
1347
}
1346
1348
break ;
1347
1349
@@ -1801,14 +1803,19 @@ size_t http_parser_execute (http_parser *parser,
1801
1803
REEXECUTE ();
1802
1804
}
1803
1805
1804
- /* Cannot us transfer-encoding and a content-length header together
1806
+ /* Cannot use transfer-encoding and a content-length header together
1805
1807
per the HTTP specification. (RFC 7230 Section 3.3.3) */
1806
- if ((parser -> extra_flags & ( F_TRANSFER_ENCODING >> 8 ) ) &&
1808
+ if ((parser -> uses_transfer_encoding == 1 ) &&
1807
1809
(parser -> flags & F_CONTENTLENGTH )) {
1808
1810
/* Allow it for lenient parsing as long as `Transfer-Encoding` is
1809
- * not `chunked`
1811
+ * not `chunked` or allow_length_with_encoding is set
1810
1812
*/
1811
- if (!lenient || (parser -> flags & F_CHUNKED )) {
1813
+ if (parser -> flags & F_CHUNKED ) {
1814
+ if (!allow_chunked_length ) {
1815
+ SET_ERRNO (HPE_UNEXPECTED_CONTENT_LENGTH );
1816
+ goto error ;
1817
+ }
1818
+ } else if (!lenient ) {
1812
1819
SET_ERRNO (HPE_UNEXPECTED_CONTENT_LENGTH );
1813
1820
goto error ;
1814
1821
}
@@ -1889,7 +1896,7 @@ size_t http_parser_execute (http_parser *parser,
1889
1896
/* chunked encoding - ignore Content-Length header,
1890
1897
* prepare for a chunk */
1891
1898
UPDATE_STATE (s_chunk_size_start );
1892
- } else if (parser -> extra_flags & ( F_TRANSFER_ENCODING >> 8 ) ) {
1899
+ } else if (parser -> uses_transfer_encoding == 1 ) {
1893
1900
if (parser -> type == HTTP_REQUEST && !lenient ) {
1894
1901
/* RFC 7230 3.3.3 */
1895
1902
@@ -2165,7 +2172,7 @@ http_message_needs_eof (const http_parser *parser)
2165
2172
}
2166
2173
2167
2174
/* RFC 7230 3.3.3, see `s_headers_almost_done` */
2168
- if ((parser -> extra_flags & ( F_TRANSFER_ENCODING >> 8 ) ) &&
2175
+ if ((parser -> uses_transfer_encoding == 1 ) &&
2169
2176
(parser -> flags & F_CHUNKED ) == 0 ) {
2170
2177
return 1 ;
2171
2178
}
0 commit comments