diff --git a/lib/nghttp2_hd_huffman.c b/lib/nghttp2_hd_huffman.c index c1713ddf..608cc0f2 100644 --- a/lib/nghttp2_hd_huffman.c +++ b/lib/nghttp2_hd_huffman.c @@ -179,10 +179,8 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, for(j = 0; j < 2; ++j) { const nghttp2_huff_decode *t; - assert(ctx->state >= 0); - t = &huff_decode_table[ctx->state][in]; - if(t->state == -1) { + if(t->flags & NGHTTP2_HUFF_FAIL) { return NGHTTP2_ERR_HEADER_COMP; } if(t->flags & NGHTTP2_HUFF_SYM) { diff --git a/lib/nghttp2_hd_huffman.h b/lib/nghttp2_hd_huffman.h index c0ee6f1d..7107fd9c 100644 --- a/lib/nghttp2_hd_huffman.h +++ b/lib/nghttp2_hd_huffman.h @@ -36,13 +36,17 @@ typedef enum { sequence. */ NGHTTP2_HUFF_ACCEPTED = 1, /* This state emits symbol */ - NGHTTP2_HUFF_SYM = (1 << 1) + NGHTTP2_HUFF_SYM = (1 << 1), + /* If state machine reaches this state, decoding fails. */ + NGHTTP2_HUFF_FAIL = (1 << 2), } nghttp2_huff_decode_flag; typedef struct { /* huffman decoding state, which is actually the node ID of internal - huffman tree */ - int16_t state; + huffman tree. We have 257 leaf nodes, but they are identical to + root node other than emitting a symbol, so we have 256 internal + nodes [1..255], inclusive. */ + uint8_t state; /* bitwise OR of zero or more of the nghttp2_huff_decode_flag */ uint8_t flags; /* symbol if NGHTTP2_HUFF_SYM flag set */ @@ -54,7 +58,7 @@ typedef nghttp2_huff_decode huff_decode_table_type[16]; typedef struct { /* Current huffman decoding state. We stripped leaf nodes, so the value range is [0..255], inclusive. */ - int16_t state; + uint8_t state; /* nonzero if we can say that the decoding process succeeds at this state */ uint8_t accept; diff --git a/lib/nghttp2_hd_huffman_data.c b/lib/nghttp2_hd_huffman_data.c index d9d534f1..8d2a646d 100644 --- a/lib/nghttp2_hd_huffman_data.c +++ b/lib/nghttp2_hd_huffman_data.c @@ -3624,7 +3624,7 @@ const nghttp2_huff_decode huff_decode_table[][16] = { {0, 0x03, 253}, {0, 0x03, 254}, {0, 0x03, 255}, - {-1, 0x00, 0}, + {0, 0x04, 0}, {189, 0x00, 0}, {191, 0x00, 0}, {192, 0x00, 0}, @@ -3772,8 +3772,8 @@ const nghttp2_huff_decode huff_decode_table[][16] = { {14, 0x03, 254}, {1, 0x02, 255}, {14, 0x03, 255}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, {0, 0x03, 0}, {0, 0x03, 1}, {0, 0x03, 2}, @@ -3840,10 +3840,10 @@ const nghttp2_huff_decode huff_decode_table[][16] = { }, /* 187 */ { - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, {1, 0x02, 0}, {14, 0x03, 0}, {1, 0x02, 1}, @@ -3859,14 +3859,14 @@ const nghttp2_huff_decode huff_decode_table[][16] = { }, /* 188 */ { - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, - {-1, 0x00, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, + {0, 0x04, 0}, {2, 0x02, 0}, {6, 0x02, 0}, {15, 0x02, 0}, diff --git a/mkhufftbl.py b/mkhufftbl.py index f1c99785..4cff3acd 100755 --- a/mkhufftbl.py +++ b/mkhufftbl.py @@ -84,6 +84,7 @@ def dfs(node, root): NGHTTP2_HUFF_ACCEPTED = 1 NGHTTP2_HUFF_SYM = 1 << 1 +NGHTTP2_HUFF_FAIL = 1 << 2 def dfs_print(node): if node.term is not None: @@ -100,7 +101,8 @@ def dfs_print(node): out = syms[0] flags |= NGHTTP2_HUFF_SYM if nd is None: - id = -1 + id = 0 + flags |= NGHTTP2_HUFF_FAIL else: id = nd.id if id is None: @@ -159,13 +161,14 @@ print '' print '''\ enum {{ NGHTTP2_HUFF_ACCEPTED = {}, - NGHTTP2_HUFF_SYM = {} + NGHTTP2_HUFF_SYM = {}, + NGHTTP2_HUFF_FAIL = {}, }} nghttp2_huff_decode_flag; -'''.format(NGHTTP2_HUFF_ACCEPTED, NGHTTP2_HUFF_SYM) +'''.format(NGHTTP2_HUFF_ACCEPTED, NGHTTP2_HUFF_SYM, NGHTTP2_HUFF_FAIL) print '''\ typedef struct { - int16_t state; + uint8_t state; uint8_t flags; uint8_t sym; } nghttp2_huff_decode;