[9.20] chg: dev: Update picohttpparser.{c,h} with upstream repository

Closes #4485

Backport of MR !9857

Merge branch 'backport-4485-update-httppicoparser-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!9863
This commit is contained in:
Ondřej Surý 2024-12-08 13:15:51 +00:00
commit 3c9657a3f4
2 changed files with 43 additions and 13 deletions

View file

@ -54,16 +54,16 @@
#define IS_PRINTABLE_ASCII(c) ((unsigned char)(c) - 040u < 0137u)
#define CHECK_EOF() \
if (buf == buf_end) { \
*ret = -2; \
return (NULL); \
#define CHECK_EOF() \
if (buf == buf_end) { \
*ret = -2; \
return NULL; \
}
#define EXPECT_CHAR_NO_CHECK(ch) \
if (*buf++ != ch) { \
*ret = -1; \
return (NULL); \
return NULL; \
}
#define EXPECT_CHAR(ch) \
@ -88,7 +88,7 @@
*buf == '\177') \
{ \
*ret = -1; \
return (NULL); \
return NULL; \
} \
} \
++buf; \
@ -154,17 +154,19 @@ get_token_to_eol(const char *buf, const char *buf_end, const char **token,
"\177\177"; /* allow chars w. MSB set */
int found;
buf = findchar_fast(buf, buf_end, ranges1, 6, &found);
if (found)
if (found) {
goto FOUND_CTL;
}
#else
/* find non-printable char within the next 8 bytes, this is the hottest
* code; manually inlined */
while (likely(buf_end - buf >= 8)) {
#define DOIT() \
do { \
if (unlikely(!IS_PRINTABLE_ASCII(*buf))) \
goto NonPrintable; \
++buf; \
#define DOIT() \
do { \
if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \
goto NonPrintable; \
} \
++buf; \
} while (0)
DOIT();
DOIT();
@ -246,7 +248,7 @@ is_complete(const char *buf, const char *buf_end, size_t last_len, int *ret) {
if (*buf < '0' || '9' < *buf) { \
buf++; \
*ret = -1; \
return (NULL); \
return NULL; \
} \
*(valp_) = (mul_) * (*buf++ - '0');
@ -603,6 +605,8 @@ phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf,
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:
@ -616,6 +620,20 @@ phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf,
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) {
@ -727,6 +745,15 @@ Exit:
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;
}

View file

@ -29,6 +29,7 @@
#ifndef picohttpparser_h
#define picohttpparser_h
#include <stdint.h>
#include <sys/types.h>
#ifdef _MSC_VER
@ -74,6 +75,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-