From 5ae9bb8925c1cb1e945b41d140367f27b3dd5c98 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 9 Nov 2019 17:18:11 +0900 Subject: [PATCH] Fail fast if huffman decoding context is in failure state --- lib/nghttp2_hd.c | 5 +++++ lib/nghttp2_hd.h | 6 ++++++ lib/nghttp2_hd_huffman.c | 4 ++++ tests/nghttp2_hd_test.c | 8 ++++++++ 4 files changed, 23 insertions(+) diff --git a/lib/nghttp2_hd.c b/lib/nghttp2_hd.c index 11ca3345..5e869315 100644 --- a/lib/nghttp2_hd.c +++ b/lib/nghttp2_hd.c @@ -1694,6 +1694,11 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater, DEBUGF("inflatehd: huffman decoding failed\n"); return readlen; } + if (nghttp2_hd_huff_decode_failure_state(&inflater->huff_decode_ctx)) { + DEBUGF("inflatehd: huffman decoding failed\n"); + return NGHTTP2_ERR_HEADER_COMP; + } + inflater->left -= (size_t)readlen; return readlen; } diff --git a/lib/nghttp2_hd.h b/lib/nghttp2_hd.h index 14ae9807..26740288 100644 --- a/lib/nghttp2_hd.h +++ b/lib/nghttp2_hd.h @@ -430,4 +430,10 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, nghttp2_buf *buf, const uint8_t *src, size_t srclen, int fin); +/* + * nghttp2_hd_huff_decode_failure_state returns nonzero if |ctx| + * indicates that huffman decoding context is in failure state. + */ +int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx); + #endif /* NGHTTP2_HD_H */ diff --git a/lib/nghttp2_hd_huffman.c b/lib/nghttp2_hd_huffman.c index 889280e0..ac90f49c 100644 --- a/lib/nghttp2_hd_huffman.c +++ b/lib/nghttp2_hd_huffman.c @@ -138,3 +138,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, return (ssize_t)srclen; } + +int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) { + return ctx->fstate == 0x100; +} diff --git a/tests/nghttp2_hd_test.c b/tests/nghttp2_hd_test.c index f14a84fd..74725d40 100644 --- a/tests/nghttp2_hd_test.c +++ b/tests/nghttp2_hd_test.c @@ -1566,4 +1566,12 @@ void test_nghttp2_hd_huff_decode(void) { len = nghttp2_hd_huff_decode(&ctx, &outbuf, e, 2, 6); CU_ASSERT(NGHTTP2_ERR_HEADER_COMP == len); + + /* Check failure state */ + nghttp2_buf_wrap_init(&outbuf, b, sizeof(b)); + nghttp2_hd_huff_decode_context_init(&ctx); + len = nghttp2_hd_huff_decode(&ctx, &outbuf, e, 5, 0); + + CU_ASSERT(5 == len); + CU_ASSERT(nghttp2_hd_huff_decode_failure_state(&ctx)); }