Skip to content

Commit

Permalink
deps: update nghttp2 to 1.40.0
Browse files Browse the repository at this point in the history
PR-URL: #30493
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information
gengjiawen authored and targos committed Dec 1, 2019
1 parent 2ad7003 commit 2960ef1
Show file tree
Hide file tree
Showing 11 changed files with 4,387 additions and 4,432 deletions.
2 changes: 1 addition & 1 deletion deps/nghttp2/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
set_target_properties(nghttp2_static PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
ARCHIVE_OUTPUT_NAME nghttp2
ARCHIVE_OUTPUT_NAME nghttp2_static
)
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
if(ENABLE_STATIC_LIB)
Expand Down
13 changes: 13 additions & 0 deletions deps/nghttp2/lib/includes/nghttp2/nghttp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -4769,6 +4769,19 @@ NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len);
*/
NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len);

/**
* @function
*
* Returns nonzero if the |value| which is supposed to the value of
* :authority or host header field is valid according to
* https://tools.ietf.org/html/rfc3986#section-3.2
*
* |value| is valid if it merely consists of the allowed characters.
* In particular, it does not check whether |value| follows the syntax
* of authority.
*/
NGHTTP2_EXTERN int nghttp2_check_authority(const uint8_t *value, size_t len);

/* HPACK API */

struct nghttp2_hd_deflater;
Expand Down
4 changes: 2 additions & 2 deletions deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
* @macro
* Version number of the nghttp2 library release
*/
#define NGHTTP2_VERSION "1.39.2"
#define NGHTTP2_VERSION "1.40.0"

/**
* @macro
* Numerical representation of the version number of the nghttp2 library
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
#define NGHTTP2_VERSION_NUM 0x012702
#define NGHTTP2_VERSION_NUM 0x012800

#endif /* NGHTTP2VER_H */
5 changes: 5 additions & 0 deletions deps/nghttp2/lib/nghttp2_hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
6 changes: 6 additions & 0 deletions deps/nghttp2/lib/nghttp2_hd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
223 changes: 68 additions & 155 deletions deps/nghttp2/lib/nghttp2_hd_huffman.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,114 +29,7 @@
#include <stdio.h>

#include "nghttp2_hd.h"

/*
* Encodes huffman code |sym| into |*dest_ptr|, whose least |rembits|
* bits are not filled yet. The |rembits| must be in range [1, 8],
* inclusive. At the end of the process, the |*dest_ptr| is updated
* and points where next output should be placed. The number of
* unfilled bits in the pointed location is returned.
*/
static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr,
size_t rembits, const nghttp2_huff_sym *sym) {
int rv;
size_t nbits = sym->nbits;
uint32_t code = sym->code;

/* We assume that sym->nbits <= 32 */
if (rembits > nbits) {
nghttp2_bufs_fast_orb_hold(bufs, (uint8_t)(code << (rembits - nbits)));
return (ssize_t)(rembits - nbits);
}

if (rembits == nbits) {
nghttp2_bufs_fast_orb(bufs, (uint8_t)code);
--*avail_ptr;
return 8;
}

nghttp2_bufs_fast_orb(bufs, (uint8_t)(code >> (nbits - rembits)));
--*avail_ptr;

nbits -= rembits;
if (nbits & 0x7) {
/* align code to MSB byte boundary */
code <<= 8 - (nbits & 0x7);
}

if (*avail_ptr < (nbits + 7) / 8) {
/* slow path */
if (nbits > 24) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 24));
if (rv != 0) {
return rv;
}
nbits -= 8;
}
if (nbits > 16) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 16));
if (rv != 0) {
return rv;
}
nbits -= 8;
}
if (nbits > 8) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 8));
if (rv != 0) {
return rv;
}
nbits -= 8;
}
if (nbits == 8) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)code);
if (rv != 0) {
return rv;
}
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
return 8;
}

rv = nghttp2_bufs_addb_hold(bufs, (uint8_t)code);
if (rv != 0) {
return rv;
}
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
return (ssize_t)(8 - nbits);
}

/* fast path, since most code is less than 8 */
if (nbits < 8) {
nghttp2_bufs_fast_addb_hold(bufs, (uint8_t)code);
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
return (ssize_t)(8 - nbits);
}

/* handle longer code path */
if (nbits > 24) {
nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 24));
nbits -= 8;
}

if (nbits > 16) {
nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 16));
nbits -= 8;
}

if (nbits > 8) {
nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 8));
nbits -= 8;
}

if (nbits == 8) {
nghttp2_bufs_fast_addb(bufs, (uint8_t)code);
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
return 8;
}

nghttp2_bufs_fast_addb_hold(bufs, (uint8_t)code);
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
return (ssize_t)(8 - nbits);
}
#include "nghttp2_net.h"

size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) {
size_t i;
Expand All @@ -151,81 +44,101 @@ size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) {

int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
size_t srclen) {
int rv;
ssize_t rembits = 8;
size_t i;
const nghttp2_huff_sym *sym;
const uint8_t *end = src + srclen;
uint64_t code = 0;
uint32_t x;
size_t nbits = 0;
size_t avail;
int rv;

avail = nghttp2_bufs_cur_avail(bufs);

for (i = 0; i < srclen; ++i) {
const nghttp2_huff_sym *sym = &huff_sym_table[src[i]];
if (rembits == 8) {
if (avail) {
nghttp2_bufs_fast_addb_hold(bufs, 0);
} else {
rv = nghttp2_bufs_addb_hold(bufs, 0);
if (rv != 0) {
return rv;
}
avail = nghttp2_bufs_cur_avail(bufs);
for (; src != end;) {
sym = &huff_sym_table[*src++];
code |= (uint64_t)sym->code << (32 - nbits);
nbits += sym->nbits;
if (nbits < 32) {
continue;
}
if (avail >= 4) {
x = htonl((uint32_t)(code >> 32));
memcpy(bufs->cur->buf.last, &x, 4);
bufs->cur->buf.last += 4;
avail -= 4;
code <<= 32;
nbits -= 32;
continue;
}

for (; nbits >= 8;) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56));
if (rv != 0) {
return rv;
}
code <<= 8;
nbits -= 8;
}
rembits = huff_encode_sym(bufs, &avail, (size_t)rembits, sym);
if (rembits < 0) {
return (int)rembits;

avail = nghttp2_bufs_cur_avail(bufs);
}

for (; nbits >= 8;) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56));
if (rv != 0) {
return rv;
}
code <<= 8;
nbits -= 8;
}
/* 256 is special terminal symbol, pad with its prefix */
if (rembits < 8) {
/* if rembits < 8, we should have at least 1 buffer space
available */
const nghttp2_huff_sym *sym = &huff_sym_table[256];
assert(avail);
/* Caution we no longer adjust avail here */
nghttp2_bufs_fast_orb(
bufs, (uint8_t)(sym->code >> (sym->nbits - (size_t)rembits)));

if (nbits) {
rv = nghttp2_bufs_addb(
bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1)));
if (rv != 0) {
return rv;
}
}

return 0;
}

void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->state = 0;
ctx->accept = 1;
ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
}

ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final) {
size_t i;
const uint8_t *end = src + srclen;
nghttp2_huff_decode node = {ctx->fstate, 0};
const nghttp2_huff_decode *t = &node;
uint8_t c;

/* We use the decoding algorithm described in
http://graphics.ics.uci.edu/pub/Prefix.pdf */
for (i = 0; i < srclen; ++i) {
const nghttp2_huff_decode *t;

t = &huff_decode_table[ctx->state][src[i] >> 4];
if (t->flags & NGHTTP2_HUFF_FAIL) {
return NGHTTP2_ERR_HEADER_COMP;
}
if (t->flags & NGHTTP2_HUFF_SYM) {
for (; src != end;) {
c = *src++;
t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
}

t = &huff_decode_table[t->state][src[i] & 0xf];
if (t->flags & NGHTTP2_HUFF_FAIL) {
return NGHTTP2_ERR_HEADER_COMP;
}
if (t->flags & NGHTTP2_HUFF_SYM) {
t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
}

ctx->state = t->state;
ctx->accept = (t->flags & NGHTTP2_HUFF_ACCEPTED) != 0;
}
if (final && !ctx->accept) {

ctx->fstate = t->fstate;

if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) {
return NGHTTP2_ERR_HEADER_COMP;
}
return (ssize_t)i;

return (ssize_t)srclen;
}

int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) {
return ctx->fstate == 0x100;
}
29 changes: 12 additions & 17 deletions deps/nghttp2/lib/nghttp2_hd_huffman.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,29 @@
typedef enum {
/* FSA accepts this state as the end of huffman encoding
sequence. */
NGHTTP2_HUFF_ACCEPTED = 1,
NGHTTP2_HUFF_ACCEPTED = 1 << 14,
/* This state emits symbol */
NGHTTP2_HUFF_SYM = (1 << 1),
/* If state machine reaches this state, decoding fails. */
NGHTTP2_HUFF_FAIL = (1 << 2)
NGHTTP2_HUFF_SYM = 1 << 15,
} nghttp2_huff_decode_flag;

typedef struct {
/* huffman decoding state, which is actually the node ID of internal
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;
/* fstate is the current huffman decoding state, which is actually
the node ID of internal huffman tree with
nghttp2_huff_decode_flag OR-ed. 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. The node ID 256 is
a special node and it is a terminal state that means decoding
failed. */
uint16_t fstate;
/* symbol if NGHTTP2_HUFF_SYM flag set */
uint8_t sym;
} nghttp2_huff_decode;

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. */
uint8_t state;
/* nonzero if we can say that the decoding process succeeds at this
state */
uint8_t accept;
/* fstate is the current huffman decoding state. */
uint16_t fstate;
} nghttp2_hd_huff_decode_context;

typedef struct {
Expand Down
Loading

0 comments on commit 2960ef1

Please sign in to comment.