forked from cory/tildefriends
		
	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; | ||||
|     ssize_t ret = -2; /* incomplete */ | ||||
|  | ||||
|     decoder->_total_read += bufsz; | ||||
|  | ||||
|     while (1) { | ||||
|         switch (decoder->_state) { | ||||
|         case CHUNKED_IN_CHUNK_SIZE: | ||||
| @@ -557,6 +559,18 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | ||||
|                         ret = -1; | ||||
|                         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; | ||||
|                 } | ||||
|                 if (decoder->_hex_count == sizeof(size_t) * 2) { | ||||
| @@ -652,6 +666,12 @@ Exit: | ||||
|     if (dst != src) | ||||
|         memmove(buf + dst, buf + src, bufsz - src); | ||||
|     *_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; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								deps/picohttpparser/picohttpparser.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								deps/picohttpparser/picohttpparser.h
									
									
									
									
										vendored
									
									
								
							| @@ -27,6 +27,7 @@ | ||||
| #ifndef picohttpparser_h | ||||
| #define picohttpparser_h | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
| @@ -64,6 +65,8 @@ struct phr_chunked_decoder { | ||||
|     char consume_trailer;       /* if trailing headers should be consumed */ | ||||
|     char _hex_count; | ||||
|     char _state; | ||||
|     uint64_t _total_read; | ||||
|     uint64_t _total_overhead; | ||||
| }; | ||||
|  | ||||
| /* 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, "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\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", | ||||
|                                 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); | ||||
| @@ -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\nfffffffffffffffff\r\nabcdefg", -1); | ||||
|     } | ||||
|     test_chunked_failure(__LINE__, "1x\r\na\r\n0\r\n", -1); | ||||
| } | ||||
|  | ||||
| static void test_chunked_consume_trailer(void) | ||||
| @@ -456,6 +458,53 @@ static void test_chunked_leftdata(void) | ||||
| #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) | ||||
| { | ||||
|     long pagesize = sysconf(_SC_PAGESIZE); | ||||
| @@ -472,6 +521,7 @@ int main(void) | ||||
|     subtest("chunked", test_chunked); | ||||
|     subtest("chunked-consume-trailer", test_chunked_consume_trailer); | ||||
|     subtest("chunked-leftdata", test_chunked_leftdata); | ||||
|     subtest("chunked-overhead", test_chunked_overhead); | ||||
|  | ||||
|     munmap(inputbuf - pagesize * 2, pagesize * 3); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user