]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Update picohttpparser.{c,h} with upstream repository
authorOndřej Surý <ondrej@isc.org>
Fri, 6 Dec 2024 17:29:39 +0000 (18:29 +0100)
committerOndřej Surý <ondrej@isc.org>
Sun, 8 Dec 2024 11:14:37 +0000 (11:14 +0000)
Upstream code doesn't do regular releases, so we need to regularly
sync the code from the upstream repository.  This is synchronization up
to the commit f8d0513 from Jan 29, 2024.

lib/isc/picohttpparser.c
lib/isc/picohttpparser.h

index df8f62d92f9aaf87c4b131522ad705f276cfe654..708265f60e759ec68e01278f15a04a0667ee5d48 100644 (file)
 
 #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;
 }
 
index 0657cb29c4b192d5ce7d2775f9b69aca540230cf..27df3b92d9bac734a4c9794878b0c4dbecc3529e 100644 (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-