Commit 8da20975 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Always allocate buffer for name, and value

parent eb393985
...@@ -73,7 +73,7 @@ typedef struct { ...@@ -73,7 +73,7 @@ typedef struct {
/* /*
* Initializes the |buf|. No memory is allocated in this function. Use * Initializes the |buf|. No memory is allocated in this function. Use
* nghttp2_buf_reserve() or nghttp2_buf_reserve2() to allocate memory. * nghttp2_buf_reserve() to allocate memory.
*/ */
void nghttp2_buf_init(nghttp2_buf *buf); void nghttp2_buf_init(nghttp2_buf *buf);
......
This diff is collapsed.
...@@ -276,7 +276,7 @@ struct nghttp2_hd_deflater { ...@@ -276,7 +276,7 @@ struct nghttp2_hd_deflater {
struct nghttp2_hd_inflater { struct nghttp2_hd_inflater {
nghttp2_hd_context ctx; nghttp2_hd_context ctx;
/* header buffer */ /* header buffer */
nghttp2_bufs nvbufs; nghttp2_buf namebuf, valuebuf;
/* Stores current state of huffman decoding */ /* Stores current state of huffman decoding */
nghttp2_hd_huff_decode_context huff_decode_ctx; nghttp2_hd_huff_decode_context huff_decode_ctx;
/* Pointer to the nghttp2_hd_entry which is used current header /* Pointer to the nghttp2_hd_entry which is used current header
...@@ -285,14 +285,11 @@ struct nghttp2_hd_inflater { ...@@ -285,14 +285,11 @@ struct nghttp2_hd_inflater {
nghttp2_hd_entry *ent_keep; nghttp2_hd_entry *ent_keep;
/* Pointer to the name/value pair buffer which is used in the /* Pointer to the name/value pair buffer which is used in the
current header emission. */ current header emission. */
uint8_t *nv_keep; uint8_t *nv_name_keep, *nv_value_keep;
/* The number of bytes to read */ /* The number of bytes to read */
size_t left; size_t left;
/* The index in indexed repr or indexed name */ /* The index in indexed repr or indexed name */
size_t index; size_t index;
/* The length of new name encoded in literal. For huffman encoded
string, this is the length after it is decoded. */
size_t newnamelen;
/* The maximum header table size the inflater supports. This is the /* The maximum header table size the inflater supports. This is the
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */ same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
size_t settings_hd_table_bufsize_max; size_t settings_hd_table_bufsize_max;
...@@ -470,11 +467,10 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src, ...@@ -470,11 +467,10 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx); void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
/* /*
* Decodes the given data |src| with length |srclen|. The |ctx| must * Decodes the given data |src| with length |srclen|. The |ctx| must
* be initialized by nghttp2_hd_huff_decode_context_init(). The result * be initialized by nghttp2_hd_huff_decode_context_init(). The result
* will be added to |dest|. This function may expand |dest| as * will be written to |buf|. This function assumes that |buf| has the
* needed. The caller is responsible to release the memory of |dest| * enough room to store the decoded byte string.
* by calling nghttp2_bufs_free().
* *
* The caller must set the |final| to nonzero if the given input is * The caller must set the |final| to nonzero if the given input is
* the final block. * the final block.
...@@ -486,13 +482,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx); ...@@ -486,13 +482,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
* *
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_BUFFER_ERROR
* Maximum buffer capacity size exceeded.
* NGHTTP2_ERR_HEADER_COMP * NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed. * Decoding process has failed.
*/ */
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_bufs *bufs, const uint8_t *src, nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final); size_t srclen, int final);
#endif /* NGHTTP2_HD_H */ #endif /* NGHTTP2_HD_H */
...@@ -166,31 +166,10 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) { ...@@ -166,31 +166,10 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->accept = 1; ctx->accept = 1;
} }
/* Use macro to make the code simpler..., but error case is tricky.
We spent most of the CPU in decoding, so we are doing this
thing. */
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
do { \
if ((avail)) { \
nghttp2_bufs_fast_addb((bufs), (sym)); \
--(avail); \
} else { \
rv = nghttp2_bufs_addb((bufs), (sym)); \
if (rv != 0) { \
return rv; \
} \
(avail) = nghttp2_bufs_cur_avail((bufs)); \
} \
} while (0)
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_bufs *bufs, const uint8_t *src, nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final) { size_t srclen, int final) {
size_t i; size_t i;
int rv;
size_t avail;
avail = nghttp2_bufs_cur_avail(bufs);
/* We use the decoding algorithm described in /* We use the decoding algorithm described in
http://graphics.ics.uci.edu/pub/Prefix.pdf */ http://graphics.ics.uci.edu/pub/Prefix.pdf */
...@@ -202,8 +181,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, ...@@ -202,8 +181,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return NGHTTP2_ERR_HEADER_COMP; return NGHTTP2_ERR_HEADER_COMP;
} }
if (t->flags & NGHTTP2_HUFF_SYM) { if (t->flags & NGHTTP2_HUFF_SYM) {
/* this is macro, and may return from this function on error */ *buf->last++ = t->sym;
hd_huff_decode_sym_emit(bufs, t->sym, avail);
} }
t = &huff_decode_table[t->state][src[i] & 0xf]; t = &huff_decode_table[t->state][src[i] & 0xf];
...@@ -211,8 +189,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, ...@@ -211,8 +189,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return NGHTTP2_ERR_HEADER_COMP; return NGHTTP2_ERR_HEADER_COMP;
} }
if (t->flags & NGHTTP2_HUFF_SYM) { if (t->flags & NGHTTP2_HUFF_SYM) {
/* this is macro, and may return from this function on error */ *buf->last++ = t->sym;
hd_huff_decode_sym_emit(bufs, t->sym, avail);
} }
ctx->state = t->state; ctx->state = t->state;
......
...@@ -1352,13 +1352,15 @@ void test_nghttp2_hd_decode_length(void) { ...@@ -1352,13 +1352,15 @@ void test_nghttp2_hd_decode_length(void) {
void test_nghttp2_hd_huff_encode(void) { void test_nghttp2_hd_huff_encode(void) {
int rv; int rv;
ssize_t len; ssize_t len;
nghttp2_bufs bufs, outbufs; nghttp2_buf outbuf;
nghttp2_bufs bufs;
nghttp2_hd_huff_decode_context ctx; nghttp2_hd_huff_decode_context ctx;
const uint8_t t1[] = {22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, const uint8_t t1[] = {22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
uint8_t b[256];
nghttp2_buf_wrap_init(&outbuf, b, sizeof(b));
frame_pack_bufs_init(&bufs); frame_pack_bufs_init(&bufs);
frame_pack_bufs_init(&outbufs);
rv = nghttp2_hd_huff_encode(&bufs, t1, sizeof(t1)); rv = nghttp2_hd_huff_encode(&bufs, t1, sizeof(t1));
...@@ -1366,14 +1368,13 @@ void test_nghttp2_hd_huff_encode(void) { ...@@ -1366,14 +1368,13 @@ void test_nghttp2_hd_huff_encode(void) {
nghttp2_hd_huff_decode_context_init(&ctx); nghttp2_hd_huff_decode_context_init(&ctx);
len = nghttp2_hd_huff_decode(&ctx, &outbufs, bufs.cur->buf.pos, len = nghttp2_hd_huff_decode(&ctx, &outbuf, bufs.cur->buf.pos,
nghttp2_bufs_len(&bufs), 1); nghttp2_bufs_len(&bufs), 1);
CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == len); CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == len);
CU_ASSERT((ssize_t)sizeof(t1) == nghttp2_bufs_len(&outbufs)); CU_ASSERT((ssize_t)sizeof(t1) == nghttp2_buf_len(&outbuf));
CU_ASSERT(0 == memcmp(t1, outbufs.cur->buf.pos, sizeof(t1))); CU_ASSERT(0 == memcmp(t1, outbuf.pos, sizeof(t1)));
nghttp2_bufs_free(&bufs); nghttp2_bufs_free(&bufs);
nghttp2_bufs_free(&outbufs);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment