|
| 1 | +diff --git a/lib/nghttp2/lib/includes/nghttp2/nghttp2.h b/lib/nghttp2/lib/includes/nghttp2/nghttp2.h |
| 2 | +index 66ea3c63c..5378daf43 100644 |
| 3 | +--- a/lib/nghttp2/lib/includes/nghttp2/nghttp2.h |
| 4 | ++++ b/lib/nghttp2/lib/includes/nghttp2/nghttp2.h |
| 5 | +@@ -440,7 +440,12 @@ typedef enum { |
| 6 | + * exhaustion on server side to send these frames forever and does |
| 7 | + * not read network. |
| 8 | + */ |
| 9 | +- NGHTTP2_ERR_FLOODED = -904 |
| 10 | ++ NGHTTP2_ERR_FLOODED = -904, |
| 11 | ++ /** |
| 12 | ++ * When a local endpoint receives too many CONTINUATION frames |
| 13 | ++ * following a HEADER frame. |
| 14 | ++ */ |
| 15 | ++ NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905, |
| 16 | + } nghttp2_error; |
| 17 | + |
| 18 | + /** |
| 19 | +diff --git a/lib/nghttp2/lib/nghttp2_helper.c b/lib/nghttp2/lib/nghttp2_helper.c |
| 20 | +index 93dd4754b..b3563d98e 100644 |
| 21 | +--- a/lib/nghttp2/lib/nghttp2_helper.c |
| 22 | ++++ b/lib/nghttp2/lib/nghttp2_helper.c |
| 23 | +@@ -336,6 +336,8 @@ const char *nghttp2_strerror(int error_code) { |
| 24 | + "closed"; |
| 25 | + case NGHTTP2_ERR_TOO_MANY_SETTINGS: |
| 26 | + return "SETTINGS frame contained more than the maximum allowed entries"; |
| 27 | ++ case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS: |
| 28 | ++ return "Too many CONTINUATION frames following a HEADER frame"; |
| 29 | + default: |
| 30 | + return "Unknown error code"; |
| 31 | + } |
| 32 | +diff --git a/lib/nghttp2/lib/nghttp2_session.c b/lib/nghttp2/lib/nghttp2_session.c |
| 33 | +index c0d86026a..51ed4494e 100644 |
| 34 | +--- a/lib/nghttp2/lib/nghttp2_session.c |
| 35 | ++++ b/lib/nghttp2/lib/nghttp2_session.c |
| 36 | +@@ -496,6 +496,7 @@ static int session_new(nghttp2_session **session_ptr, |
| 37 | + (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN; |
| 38 | + (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM; |
| 39 | + (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS; |
| 40 | ++ (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS; |
| 41 | + |
| 42 | + if (option) { |
| 43 | + if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) && |
| 44 | +@@ -6778,6 +6779,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, |
| 45 | + } |
| 46 | + } |
| 47 | + session_inbound_frame_reset(session); |
| 48 | ++ |
| 49 | ++ session->num_continuations = 0; |
| 50 | + } |
| 51 | + break; |
| 52 | + } |
| 53 | +@@ -6899,6 +6902,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, |
| 54 | + } |
| 55 | + #endif /* DEBUGBUILD */ |
| 56 | + |
| 57 | ++ if (++session->num_continuations > session->max_continuations) { |
| 58 | ++ return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS; |
| 59 | ++ } |
| 60 | ++ |
| 61 | + readlen = inbound_frame_buf_read(iframe, in, last); |
| 62 | + in += readlen; |
| 63 | + |
| 64 | +diff --git a/lib/nghttp2/lib/nghttp2_session.h b/lib/nghttp2/lib/nghttp2_session.h |
| 65 | +index b119329a0..ef8f7b27d 100644 |
| 66 | +--- a/lib/nghttp2/lib/nghttp2_session.h |
| 67 | ++++ b/lib/nghttp2/lib/nghttp2_session.h |
| 68 | +@@ -110,6 +110,10 @@ typedef struct { |
| 69 | + #define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 |
| 70 | + #define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 |
| 71 | + |
| 72 | ++/* The default max number of CONTINUATION frames following an incoming |
| 73 | ++ HEADER frame. */ |
| 74 | ++#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8 |
| 75 | ++ |
| 76 | + /* Internal state when receiving incoming frame */ |
| 77 | + typedef enum { |
| 78 | + /* Receiving frame header */ |
| 79 | +@@ -290,6 +294,12 @@ struct nghttp2_session { |
| 80 | + size_t max_send_header_block_length; |
| 81 | + /* The maximum number of settings accepted per SETTINGS frame. */ |
| 82 | + size_t max_settings; |
| 83 | ++ /* The maximum number of CONTINUATION frames following an incoming |
| 84 | ++ HEADER frame. */ |
| 85 | ++ size_t max_continuations; |
| 86 | ++ /* The number of CONTINUATION frames following an incoming HEADER |
| 87 | ++ frame. This variable is reset when END_HEADERS flag is seen. */ |
| 88 | ++ size_t num_continuations; |
| 89 | + /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */ |
| 90 | + uint32_t next_stream_id; |
| 91 | + /* The last stream ID this session initiated. For client session, |
0 commit comments