Latest picohttpparser 4e7bc76.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4813 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										20
									
								
								deps/picohttpparser/picohttpparser.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								deps/picohttpparser/picohttpparser.c
									
									
									
									
										vendored
									
									
								
							| @@ -545,6 +545,8 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||||||
|     size_t dst = 0, src = 0, bufsz = *_bufsz; |     size_t dst = 0, src = 0, bufsz = *_bufsz; | ||||||
|     ssize_t ret = -2; /* incomplete */ |     ssize_t ret = -2; /* incomplete */ | ||||||
|  |  | ||||||
|  |     decoder->_total_read += bufsz; | ||||||
|  |  | ||||||
|     while (1) { |     while (1) { | ||||||
|         switch (decoder->_state) { |         switch (decoder->_state) { | ||||||
|         case CHUNKED_IN_CHUNK_SIZE: |         case CHUNKED_IN_CHUNK_SIZE: | ||||||
| @@ -557,6 +559,18 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||||||
|                         ret = -1; |                         ret = -1; | ||||||
|                         goto Exit; |                         goto Exit; | ||||||
|                     } |                     } | ||||||
|  |                     /* the only characters that may appear after the chunk size are BWS, semicolon, or CRLF */ | ||||||
|  |                     switch (buf[src]) { | ||||||
|  |                     case ' ': | ||||||
|  |                     case '\011': | ||||||
|  |                     case ';': | ||||||
|  |                     case '\012': | ||||||
|  |                     case '\015': | ||||||
|  |                         break; | ||||||
|  |                     default: | ||||||
|  |                         ret = -1; | ||||||
|  |                         goto Exit; | ||||||
|  |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 if (decoder->_hex_count == sizeof(size_t) * 2) { |                 if (decoder->_hex_count == sizeof(size_t) * 2) { | ||||||
| @@ -652,6 +666,12 @@ Exit: | |||||||
|     if (dst != src) |     if (dst != src) | ||||||
|         memmove(buf + dst, buf + src, bufsz - src); |         memmove(buf + dst, buf + src, bufsz - src); | ||||||
|     *_bufsz = dst; |     *_bufsz = dst; | ||||||
|  |     /* if incomplete but the overhead of the chunked encoding is >=100KB and >80%, signal an error */ | ||||||
|  |     if (ret == -2) { | ||||||
|  |         decoder->_total_overhead += bufsz - dst; | ||||||
|  |         if (decoder->_total_overhead >= 100 * 1024 && decoder->_total_read - decoder->_total_overhead < decoder->_total_read / 4) | ||||||
|  |             ret = -1; | ||||||
|  |     } | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								deps/picohttpparser/picohttpparser.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								deps/picohttpparser/picohttpparser.h
									
									
									
									
										vendored
									
									
								
							| @@ -27,6 +27,7 @@ | |||||||
| #ifndef picohttpparser_h | #ifndef picohttpparser_h | ||||||
| #define picohttpparser_h | #define picohttpparser_h | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
|  |  | ||||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||||
| @@ -64,6 +65,8 @@ struct phr_chunked_decoder { | |||||||
|     char consume_trailer;       /* if trailing headers should be consumed */ |     char consume_trailer;       /* if trailing headers should be consumed */ | ||||||
|     char _hex_count; |     char _hex_count; | ||||||
|     char _state; |     char _state; | ||||||
|  |     uint64_t _total_read; | ||||||
|  |     uint64_t _total_overhead; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* the function rewrites the buffer given as (buf, bufsz) removing the chunked- | /* the function rewrites the buffer given as (buf, bufsz) removing the chunked- | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								deps/picohttpparser/test.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								deps/picohttpparser/test.c
									
									
									
									
										vendored
									
									
								
							| @@ -410,6 +410,7 @@ static void test_chunked(void) | |||||||
|         chunked_test_runners[i](__LINE__, 0, "b\r\nhello world\r\n0\r\n", "hello world", 0); |         chunked_test_runners[i](__LINE__, 0, "b\r\nhello world\r\n0\r\n", "hello world", 0); | ||||||
|         chunked_test_runners[i](__LINE__, 0, "6\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); |         chunked_test_runners[i](__LINE__, 0, "6\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); | ||||||
|         chunked_test_runners[i](__LINE__, 0, "6;comment=hi\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); |         chunked_test_runners[i](__LINE__, 0, "6;comment=hi\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); | ||||||
|  |         chunked_test_runners[i](__LINE__, 0, "6 ; comment\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); | ||||||
|         chunked_test_runners[i](__LINE__, 0, "6\r\nhello \r\n5\r\nworld\r\n0\r\na: b\r\nc: d\r\n\r\n", "hello world", |         chunked_test_runners[i](__LINE__, 0, "6\r\nhello \r\n5\r\nworld\r\n0\r\na: b\r\nc: d\r\n\r\n", "hello world", | ||||||
|                                 sizeof("a: b\r\nc: d\r\n\r\n") - 1); |                                 sizeof("a: b\r\nc: d\r\n\r\n") - 1); | ||||||
|         chunked_test_runners[i](__LINE__, 0, "b\r\nhello world\r\n0\r\n", "hello world", 0); |         chunked_test_runners[i](__LINE__, 0, "b\r\nhello world\r\n0\r\n", "hello world", 0); | ||||||
| @@ -421,6 +422,7 @@ static void test_chunked(void) | |||||||
|         test_chunked_failure(__LINE__, "6\r\nhello \r\nffffffffffffffff\r\nabcdefg", -2); |         test_chunked_failure(__LINE__, "6\r\nhello \r\nffffffffffffffff\r\nabcdefg", -2); | ||||||
|         test_chunked_failure(__LINE__, "6\r\nhello \r\nfffffffffffffffff\r\nabcdefg", -1); |         test_chunked_failure(__LINE__, "6\r\nhello \r\nfffffffffffffffff\r\nabcdefg", -1); | ||||||
|     } |     } | ||||||
|  |     test_chunked_failure(__LINE__, "1x\r\na\r\n0\r\n", -1); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void test_chunked_consume_trailer(void) | static void test_chunked_consume_trailer(void) | ||||||
| @@ -456,6 +458,53 @@ static void test_chunked_leftdata(void) | |||||||
| #undef NEXT_REQ | #undef NEXT_REQ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static ssize_t do_test_chunked_overhead(size_t chunk_len, size_t chunk_count, const char *extra) | ||||||
|  | { | ||||||
|  |     struct phr_chunked_decoder dec = {0}; | ||||||
|  |     char buf[1024]; | ||||||
|  |     size_t bufsz; | ||||||
|  |     ssize_t ret; | ||||||
|  |  | ||||||
|  |     for (size_t i = 0; i < chunk_count; ++i) { | ||||||
|  |         /* build and feed the chunk header */ | ||||||
|  |         bufsz = (size_t)sprintf(buf, "%zx%s\r\n", chunk_len, extra); | ||||||
|  |         if ((ret = phr_decode_chunked(&dec, buf, &bufsz)) != -2) | ||||||
|  |             goto Exit; | ||||||
|  |         assert(bufsz == 0); | ||||||
|  |         /* build and feed the chunk boby */ | ||||||
|  |         memset(buf, 'A', chunk_len); | ||||||
|  |         bufsz = chunk_len; | ||||||
|  |         if ((ret = phr_decode_chunked(&dec, buf, &bufsz)) != -2) | ||||||
|  |             goto Exit; | ||||||
|  |         assert(bufsz == chunk_len); | ||||||
|  |         /* build and feed the chunk end (CRLF) */ | ||||||
|  |         strcpy(buf, "\r\n"); | ||||||
|  |         bufsz = 2; | ||||||
|  |         if ((ret = phr_decode_chunked(&dec, buf, &bufsz)) != -2) | ||||||
|  |             goto Exit; | ||||||
|  |         assert(bufsz == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* build and feed the end chunk */ | ||||||
|  |     strcpy(buf, "0\r\n\r\n"); | ||||||
|  |     bufsz = 5; | ||||||
|  |     ret = phr_decode_chunked(&dec, buf, &bufsz); | ||||||
|  |     assert(bufsz == 0); | ||||||
|  |  | ||||||
|  | Exit: | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void test_chunked_overhead(void) | ||||||
|  | { | ||||||
|  |     ok(do_test_chunked_overhead(100, 10000, "") == 2 /* consume trailer is not set */); | ||||||
|  |     ok(do_test_chunked_overhead(10, 100000, "") == 2 /* consume trailer is not set */); | ||||||
|  |     ok(do_test_chunked_overhead(1, 1000000, "") == -1); | ||||||
|  |  | ||||||
|  |     ok(do_test_chunked_overhead(10, 100000, "; tiny=1") == 2 /* consume trailer is not set */); | ||||||
|  |     ok(do_test_chunked_overhead(10, 100000, "; large=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") == -1); | ||||||
|  | } | ||||||
|  |  | ||||||
| int main(void) | int main(void) | ||||||
| { | { | ||||||
|     long pagesize = sysconf(_SC_PAGESIZE); |     long pagesize = sysconf(_SC_PAGESIZE); | ||||||
| @@ -472,6 +521,7 @@ int main(void) | |||||||
|     subtest("chunked", test_chunked); |     subtest("chunked", test_chunked); | ||||||
|     subtest("chunked-consume-trailer", test_chunked_consume_trailer); |     subtest("chunked-consume-trailer", test_chunked_consume_trailer); | ||||||
|     subtest("chunked-leftdata", test_chunked_leftdata); |     subtest("chunked-leftdata", test_chunked_leftdata); | ||||||
|  |     subtest("chunked-overhead", test_chunked_overhead); | ||||||
|  |  | ||||||
|     munmap(inputbuf - pagesize * 2, pagesize * 3); |     munmap(inputbuf - pagesize * 2, pagesize * 3); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user