deps: update nghttp2 to 1.64.0

PR-URL: https://github.com/nodejs/node/pull/55559
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
This commit is contained in:
Node.js GitHub Bot 2024-10-28 22:11:33 -04:00 committed by GitHub
parent 21d6f53329
commit ece37bc88c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 6139 additions and 6129 deletions

View File

@ -327,6 +327,7 @@ EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
EXTRACFLAG = @EXTRACFLAG@
EXTRA_DEFS = @EXTRA_DEFS@
FGREP = @FGREP@
FILECMD = @FILECMD@
GREP = @GREP@
HAVE_CXX20 = @HAVE_CXX20@
INSTALL = @INSTALL@

View File

@ -232,6 +232,7 @@ EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
EXTRACFLAG = @EXTRACFLAG@
EXTRA_DEFS = @EXTRA_DEFS@
FGREP = @FGREP@
FILECMD = @FILECMD@
GREP = @GREP@
HAVE_CXX20 = @HAVE_CXX20@
INSTALL = @INSTALL@

View File

@ -57,8 +57,8 @@ extern "C" {
#ifdef NGHTTP2_STATICLIB
# define NGHTTP2_EXTERN
#elif defined(WIN32) || (__has_declspec_attribute(dllexport) && \
__has_declspec_attribute(dllimport))
#elif defined(WIN32) || \
(__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
# ifdef BUILDING_NGHTTP2
# define NGHTTP2_EXTERN __declspec(dllexport)
# else /* !BUILDING_NGHTTP2 */
@ -6073,6 +6073,12 @@ NGHTTP2_EXTERN int nghttp2_check_path(const uint8_t *value, size_t len);
* :authority or host header field is valid according to
* https://tools.ietf.org/html/rfc3986#section-3.2
*
* Note that :authority and host field values are not authority. They
* do not include userinfo in RFC 3986, see
* https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2, that
* is, it does not include '@'. This function treats '@' as a valid
* character.
*
* |value| is valid if it merely consists of the allowed characters.
* In particular, it does not check whether |value| follows the syntax
* of authority.

View File

@ -29,7 +29,7 @@
* @macro
* Version number of the nghttp2 library release
*/
#define NGHTTP2_VERSION "1.63.0"
#define NGHTTP2_VERSION "1.64.0"
/**
* @macro
@ -37,6 +37,6 @@
* 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 0x013f00
#define NGHTTP2_VERSION_NUM 0x014000
#endif /* NGHTTP2VER_H */

View File

@ -151,8 +151,8 @@ void nghttp2_session_callbacks_set_data_source_read_length_callback(
}
void nghttp2_session_callbacks_set_data_source_read_length_callback2(
nghttp2_session_callbacks *cbs, nghttp2_data_source_read_length_callback2
data_source_read_length_callback) {
nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback2 data_source_read_length_callback) {
cbs->read_length_callback2 = data_source_read_length_callback;
}

View File

@ -1112,7 +1112,6 @@ static int add_hd_table_incremental(nghttp2_hd_context *context,
while (context->hd_table_bufsize + room > context->hd_table_bufsize_max &&
context->hd_table.len > 0) {
size_t idx = context->hd_table.len - 1;
nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx);
@ -1367,8 +1366,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
entropy secret data (e.g., id/password). Also cookie header
field with less than 20 bytes value is also never indexed. This
is the same criteria used in Firefox codebase. */
indexing_mode =
token == NGHTTP2_TOKEN_AUTHORIZATION ||
indexing_mode = token == NGHTTP2_TOKEN_AUTHORIZATION ||
(token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) ||
(nv->flags & NGHTTP2_NV_FLAG_NO_INDEX)
? NGHTTP2_HD_NEVER_INDEXING
@ -1380,7 +1378,6 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
idx = res.index;
if (res.name_value_match) {
DEBUGF("deflatehd: name/value match index=%td\n", idx);
rv = emit_indexed_block(bufs, (size_t)idx);
@ -1458,7 +1455,6 @@ int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
deflater->min_hd_table_bufsize_max = UINT32_MAX;
if (deflater->ctx.hd_table_bufsize_max > min_hd_table_bufsize_max) {
rv = emit_table_size(bufs, min_hd_table_bufsize_max);
if (rv != 0) {
@ -2051,8 +2047,8 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF;
rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1,
mem);
rv =
nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, mem);
} else {
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME;
rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem);
@ -2136,8 +2132,8 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF;
rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1,
mem);
rv =
nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem);
} else {
inflater->state = NGHTTP2_HD_STATE_READ_VALUE;
@ -2308,7 +2304,6 @@ void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater) {
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t idx,
nghttp2_nv *nv, int indexing_mode) {
return emit_indname_block(bufs, idx, nv, indexing_mode);
}

View File

@ -38,28 +38,28 @@
#define nghttp2_max_def(SUFFIX, T) \
static inline T nghttp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; }
nghttp2_max_def(int8, int8_t);
nghttp2_max_def(int16, int16_t);
nghttp2_max_def(int32, int32_t);
nghttp2_max_def(int64, int64_t);
nghttp2_max_def(uint8, uint8_t);
nghttp2_max_def(uint16, uint16_t);
nghttp2_max_def(uint32, uint32_t);
nghttp2_max_def(uint64, uint64_t);
nghttp2_max_def(size, size_t);
nghttp2_max_def(int8, int8_t)
nghttp2_max_def(int16, int16_t)
nghttp2_max_def(int32, int32_t)
nghttp2_max_def(int64, int64_t)
nghttp2_max_def(uint8, uint8_t)
nghttp2_max_def(uint16, uint16_t)
nghttp2_max_def(uint32, uint32_t)
nghttp2_max_def(uint64, uint64_t)
nghttp2_max_def(size, size_t)
#define nghttp2_min_def(SUFFIX, T) \
static inline T nghttp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; }
nghttp2_min_def(int8, int8_t);
nghttp2_min_def(int16, int16_t);
nghttp2_min_def(int32, int32_t);
nghttp2_min_def(int64, int64_t);
nghttp2_min_def(uint8, uint8_t);
nghttp2_min_def(uint16, uint16_t);
nghttp2_min_def(uint32, uint32_t);
nghttp2_min_def(uint64, uint64_t);
nghttp2_min_def(size, size_t);
nghttp2_min_def(int8, int8_t)
nghttp2_min_def(int16, int16_t)
nghttp2_min_def(int32, int32_t)
nghttp2_min_def(int64, int64_t)
nghttp2_min_def(uint8, uint8_t)
nghttp2_min_def(uint16, uint16_t)
nghttp2_min_def(uint32, uint32_t)
nghttp2_min_def(uint64, uint64_t)
nghttp2_min_def(size, size_t)
#define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0)

View File

@ -347,6 +347,84 @@ static int lws(const uint8_t *s, size_t n) {
return 1;
}
/* Generated by genauthoritychartbl.py, but '@' is not allowed */
static char VALID_AUTHORITY_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */,
0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
};
static int check_authority(const uint8_t *value, size_t len) {
const uint8_t *last;
for (last = value + len; value != last; ++value) {
if (!VALID_AUTHORITY_CHARS[*value]) {
return 0;
}
}
return 1;
}
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
nghttp2_frame *frame, nghttp2_hd_nv *nv,
int trailer) {
@ -388,7 +466,7 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
case NGHTTP2_TOKEN__AUTHORITY:
case NGHTTP2_TOKEN_HOST:
if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
rv = nghttp2_check_authority(nv->value->base, nv->value->len);
rv = check_authority(nv->value->base, nv->value->len);
} else if (
stream->flags &
NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {

View File

@ -35,8 +35,7 @@
void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
map->mem = mem;
map->tablelen = 0;
map->tablelenbits = 0;
map->hashbits = 0;
map->table = NULL;
map->size = 0;
}
@ -49,33 +48,20 @@ void nghttp2_map_free(nghttp2_map *map) {
nghttp2_mem_free(map->mem, map->table);
}
void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
uint32_t i;
nghttp2_map_bucket *bkt;
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
continue;
}
func(bkt->data, ptr);
}
}
int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
int rv;
uint32_t i;
size_t i;
nghttp2_map_bucket *bkt;
size_t tablelen;
if (map->size == 0) {
return 0;
}
for (i = 0; i < map->tablelen; ++i) {
tablelen = 1u << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
@ -91,82 +77,61 @@ int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
return 0;
}
static uint32_t hash(nghttp2_map_key_type key) {
return (uint32_t)key * 2654435769u;
static size_t hash(nghttp2_map_key_type key, size_t bits) {
return (size_t)(((uint32_t)key * 2654435769u) >> (32 - bits));
}
static size_t h2idx(uint32_t hash, uint32_t bits) {
return hash >> (32 - bits);
}
static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) {
nghttp2_map_bucket c = *a;
static size_t distance(uint32_t tablelen, uint32_t tablelenbits,
nghttp2_map_bucket *bkt, size_t idx) {
return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1);
}
static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash,
nghttp2_map_key_type *pkey, void **pdata) {
uint32_t h = bkt->hash;
nghttp2_map_key_type key = bkt->key;
void *data = bkt->data;
bkt->hash = *phash;
bkt->key = *pkey;
bkt->data = *pdata;
*phash = h;
*pkey = key;
*pdata = data;
}
static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash,
nghttp2_map_key_type key, void *data) {
bkt->hash = hash;
bkt->key = key;
bkt->data = data;
*a = *b;
*b = c;
}
#ifndef WIN32
void nghttp2_map_print_distance(nghttp2_map *map) {
uint32_t i;
void nghttp2_map_print_distance(const nghttp2_map *map) {
size_t i;
size_t idx;
nghttp2_map_bucket *bkt;
size_t tablelen;
for (i = 0; i < map->tablelen; ++i) {
if (map->size == 0) {
return;
}
tablelen = 1u << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
fprintf(stderr, "@%u <EMPTY>\n", i);
fprintf(stderr, "@%zu <EMPTY>\n", i);
continue;
}
idx = h2idx(bkt->hash, map->tablelenbits);
fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i,
bkt->hash, bkt->key, idx,
distance(map->tablelen, map->tablelenbits, bkt, idx));
idx = hash(bkt->key, map->hashbits);
fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i,
hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl);
}
}
#endif /* !WIN32 */
static int insert(nghttp2_map_bucket *table, uint32_t tablelen,
uint32_t tablelenbits, uint32_t hash,
static int insert(nghttp2_map_bucket *table, size_t hashbits,
nghttp2_map_key_type key, void *data) {
size_t idx = h2idx(hash, tablelenbits);
size_t d = 0, dd;
nghttp2_map_bucket *bkt;
size_t idx = hash(key, hashbits);
nghttp2_map_bucket b = {0, key, data}, *bkt;
size_t mask = (1u << hashbits) - 1;
for (;;) {
bkt = &table[idx];
if (bkt->data == NULL) {
map_bucket_set_data(bkt, hash, key, data);
*bkt = b;
return 0;
}
dd = distance(tablelen, tablelenbits, bkt, idx);
if (d > dd) {
map_bucket_swap(bkt, &hash, &key, &data);
d = dd;
if (b.psl > bkt->psl) {
map_bucket_swap(bkt, &b);
} else if (bkt->key == key) {
/* TODO This check is just a waste after first swap or if this
function is called from map_resize. That said, there is no
@ -175,41 +140,42 @@ static int insert(nghttp2_map_bucket *table, uint32_t tablelen,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
++d;
idx = (idx + 1) & (tablelen - 1);
++b.psl;
idx = (idx + 1) & mask;
}
}
/* new_tablelen must be power of 2 and new_tablelen == (1 <<
new_tablelenbits) must hold. */
static int map_resize(nghttp2_map *map, uint32_t new_tablelen,
uint32_t new_tablelenbits) {
uint32_t i;
static int map_resize(nghttp2_map *map, size_t new_hashbits) {
size_t i;
nghttp2_map_bucket *new_table;
nghttp2_map_bucket *bkt;
size_t tablelen;
int rv;
(void)rv;
new_table =
nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket));
new_table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
sizeof(nghttp2_map_bucket));
if (new_table == NULL) {
return NGHTTP2_ERR_NOMEM;
}
for (i = 0; i < map->tablelen; ++i) {
if (map->size) {
tablelen = 1u << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
continue;
}
rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key,
bkt->data);
rv = insert(new_table, new_hashbits, bkt->key, bkt->data);
assert(0 == rv);
}
}
nghttp2_mem_free(map->mem, map->table);
map->tablelen = new_tablelen;
map->tablelenbits = new_tablelenbits;
map->hashbits = new_hashbits;
map->table = new_table;
return 0;
@ -221,48 +187,49 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
assert(data);
/* Load factor is 0.75 */
if ((map->size + 1) * 4 > map->tablelen * 3) {
if (map->tablelen) {
rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
/* Under the very initial condition, that is map->size == 0 and
map->hashbits == 0, 4 > 3 still holds nicely. */
if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) {
if (map->hashbits) {
rv = map_resize(map, map->hashbits + 1);
if (rv != 0) {
return rv;
}
} else {
rv = map_resize(map, 1 << NGHTTP2_INITIAL_TABLE_LENBITS,
NGHTTP2_INITIAL_TABLE_LENBITS);
rv = map_resize(map, NGHTTP2_INITIAL_TABLE_LENBITS);
if (rv != 0) {
return rv;
}
}
}
rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key,
data);
rv = insert(map->table, map->hashbits, key, data);
if (rv != 0) {
return rv;
}
++map->size;
return 0;
}
void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
uint32_t h;
void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
size_t idx;
nghttp2_map_bucket *bkt;
size_t d = 0;
size_t psl = 0;
size_t mask;
if (map->size == 0) {
return NULL;
}
h = hash(key);
idx = h2idx(h, map->tablelenbits);
idx = hash(key, map->hashbits);
mask = (1u << map->hashbits) - 1;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL ||
d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
if (bkt->data == NULL || psl > bkt->psl) {
return NULL;
}
@ -270,50 +237,47 @@ void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
return bkt->data;
}
++d;
idx = (idx + 1) & (map->tablelen - 1);
++psl;
idx = (idx + 1) & mask;
}
}
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
uint32_t h;
size_t idx, didx;
nghttp2_map_bucket *bkt;
size_t d = 0;
size_t idx;
nghttp2_map_bucket *b, *bkt;
size_t psl = 0;
size_t mask;
if (map->size == 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
h = hash(key);
idx = h2idx(h, map->tablelenbits);
idx = hash(key, map->hashbits);
mask = (1u << map->hashbits) - 1;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL ||
d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
if (bkt->data == NULL || psl > bkt->psl) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (bkt->key == key) {
map_bucket_set_data(bkt, 0, 0, NULL);
didx = idx;
idx = (idx + 1) & (map->tablelen - 1);
b = bkt;
idx = (idx + 1) & mask;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL ||
distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) {
if (bkt->data == NULL || bkt->psl == 0) {
b->data = NULL;
break;
}
map->table[didx] = *bkt;
map_bucket_set_data(bkt, 0, 0, NULL);
didx = idx;
--bkt->psl;
*b = *bkt;
b = bkt;
idx = (idx + 1) & (map->tablelen - 1);
idx = (idx + 1) & mask;
}
--map->size;
@ -321,18 +285,18 @@ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
return 0;
}
++d;
idx = (idx + 1) & (map->tablelen - 1);
++psl;
idx = (idx + 1) & mask;
}
}
void nghttp2_map_clear(nghttp2_map *map) {
if (map->tablelen == 0) {
if (map->size == 0) {
return;
}
memset(map->table, 0, sizeof(*map->table) * map->tablelen);
memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits));
map->size = 0;
}
size_t nghttp2_map_size(nghttp2_map *map) { return map->size; }
size_t nghttp2_map_size(const nghttp2_map *map) { return map->size; }

View File

@ -39,7 +39,7 @@
typedef int32_t nghttp2_map_key_type;
typedef struct nghttp2_map_bucket {
uint32_t hash;
uint32_t psl;
nghttp2_map_key_type key;
void *data;
} nghttp2_map_bucket;
@ -48,33 +48,24 @@ typedef struct nghttp2_map {
nghttp2_map_bucket *table;
nghttp2_mem *mem;
size_t size;
uint32_t tablelen;
uint32_t tablelenbits;
size_t hashbits;
} nghttp2_map;
/*
* Initializes the map |map|.
* nghttp2_map_init initializes the map |map|.
*/
void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
/*
* Deallocates any resources allocated for |map|. The stored entries
* are not freed by this function. Use nghttp2_map_each_free() to free
* each entries.
* nghttp2_map_free deallocates any resources allocated for |map|.
* The stored entries are not freed by this function. Use
* nghttp2_map_each() to free each entry.
*/
void nghttp2_map_free(nghttp2_map *map);
/*
* Deallocates each entries using |func| function and any resources
* allocated for |map|. The |func| function is responsible for freeing
* given the |data| object. The |ptr| will be passed to the |func| as
* send argument. The return value of the |func| will be ignored.
*/
void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
/*
* Inserts the new |data| with the |key| to the map |map|.
* nghttp2_map_insert inserts the new |data| with the |key| to the map
* |map|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -87,52 +78,51 @@ void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data);
/*
* Returns the data associated by the key |key|. If there is no such
* data, this function returns NULL.
* nghttp2_map_find returns the entry associated by the key |key|. If
* there is no such entry, this function returns NULL.
*/
void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key);
void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key);
/*
* Removes the data associated by the key |key| from the |map|. The
* removed data is not freed by this function.
* nghttp2_map_remove removes the entry associated by the key |key|
* from the |map|. The removed entry is not freed by this function.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The data associated by |key| does not exist.
* The entry associated by |key| does not exist.
*/
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key);
/*
* Removes all entries from |map|.
* nghttp2_map_clear removes all entries from |map|. The removed
* entry is not freed by this function.
*/
void nghttp2_map_clear(nghttp2_map *map);
/*
* Returns the number of items stored in the map |map|.
* nghttp2_map_size returns the number of items stored in the map
* |map|.
*/
size_t nghttp2_map_size(nghttp2_map *map);
size_t nghttp2_map_size(const nghttp2_map *map);
/*
* Applies the function |func| to each data in the |map| with the
* optional user supplied pointer |ptr|.
* nghttp2_map_each applies the function |func| to each entry in the
* |map| with the optional user supplied pointer |ptr|.
*
* If the |func| returns 0, this function calls the |func| with the
* next data. If the |func| returns nonzero, it will not call the
* next entry. If the |func| returns nonzero, it will not call the
* |func| for further entries and return the return value of the
* |func| immediately. Thus, this function returns 0 if all the
* invocations of the |func| return 0, or nonzero value which the last
* invocation of |func| returns.
*
* Don't use this function to free each data. Use
* nghttp2_map_each_free() instead.
*/
int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
#ifndef WIN32
void nghttp2_map_print_distance(nghttp2_map *map);
void nghttp2_map_print_distance(const nghttp2_map *map);
#endif /* !WIN32 */
#endif /* NGHTTP2_MAP_H */

View File

@ -239,9 +239,9 @@ static int session_terminate_session(nghttp2_session *session,
debug_datalen = strlen(reason);
}
rv = nghttp2_session_add_goaway(session, last_stream_id, error_code,
debug_data, debug_datalen,
NGHTTP2_GOAWAY_AUX_TERM_ON_SEND);
rv =
nghttp2_session_add_goaway(session, last_stream_id, error_code, debug_data,
debug_datalen, NGHTTP2_GOAWAY_AUX_TERM_ON_SEND);
if (rv != 0) {
return rv;
@ -502,31 +502,26 @@ static int session_new(nghttp2_session **session_ptr,
if (option) {
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
option->no_auto_window_update) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE;
}
if (option->opt_set_mask & NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS) {
(*session_ptr)->remote_settings.max_concurrent_streams =
option->peer_max_concurrent_streams;
}
if (option->opt_set_mask & NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS) {
(*session_ptr)->max_incoming_reserved_streams =
option->max_reserved_remote_streams;
}
if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC) &&
option->no_recv_client_magic) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC;
}
if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) &&
option->no_http_messaging) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING;
}
@ -819,7 +814,7 @@ void nghttp2_session_del(nghttp2_session *session) {
/* Have to free streams first, so that we can check
stream->item->queued */
nghttp2_map_each_free(&session->streams, free_streams, session);
nghttp2_map_each(&session->streams, free_streams, session);
nghttp2_map_free(&session->streams);
ob_q_free(&session->ob_urgent, mem);
@ -855,7 +850,6 @@ int nghttp2_session_reprioritize_stream(
if (!dep_stream &&
session_detect_idle_stream(session, pri_spec->stream_id)) {
nghttp2_priority_spec_default_init(&pri_spec_default);
dep_stream = nghttp2_session_open_stream(
@ -1254,7 +1248,6 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
assert(headers_frame->hd.type == NGHTTP2_HEADERS);
if (headers_frame->hd.stream_id <= stream_id) {
for (item = session->ob_syn.head; item; item = item->qnext) {
aux_data = &item->aux_data.headers;
@ -1495,7 +1488,6 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
if (session->callbacks.on_stream_close_callback) {
if (session->callbacks.on_stream_close_callback(
session, stream_id, error_code, session->user_data) != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
}
@ -1701,9 +1693,9 @@ int nghttp2_session_adjust_idle_stream(nghttp2_session *session) {
/* Make minimum number of idle streams 16, and maximum 100, which
are arbitrary chosen numbers. */
max = nghttp2_min_uint32(
100, nghttp2_max_uint32(
16, nghttp2_min_uint32(
session->local_settings.max_concurrent_streams,
100,
nghttp2_max_uint32(
16, nghttp2_min_uint32(session->local_settings.max_concurrent_streams,
session->pending_local_max_concurrent_stream)));
DEBUGF("stream: adjusting kept idle streams num_idle_streams=%zu, max=%zu\n",
@ -2364,7 +2356,6 @@ static int session_prep_frame(nghttp2_session *session,
next_readmax = nghttp2_session_next_data_read(session, stream);
if (next_readmax == 0) {
/* This must be true since we only pop DATA frame item from
queue when session->remote_window_size > 0 */
assert(session->remote_window_size > 0);
@ -2377,9 +2368,9 @@ static int session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_DEFERRED;
}
rv = nghttp2_session_pack_data(session, &session->aob.framebufs,
next_readmax, frame, &item->aux_data.data,
stream);
rv =
nghttp2_session_pack_data(session, &session->aob.framebufs, next_readmax,
frame, &item->aux_data.data, stream);
if (rv == NGHTTP2_ERR_PAUSE) {
return rv;
}
@ -3074,7 +3065,6 @@ static int session_after_frame_sent1(nghttp2_session *session) {
aux_data = &item->aux_data.goaway;
if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) {
if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) {
session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT;
}
@ -3154,10 +3144,8 @@ static void session_after_frame_sent2(nghttp2_session *session) {
frame = &item->frame;
if (frame->hd.type != NGHTTP2_DATA) {
if (frame->hd.type == NGHTTP2_HEADERS ||
frame->hd.type == NGHTTP2_PUSH_PROMISE) {
if (nghttp2_bufs_next_present(framebufs)) {
framebufs->cur = framebufs->cur->next;
@ -3295,7 +3283,6 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session,
if (frame->hd.type != NGHTTP2_WINDOW_UPDATE &&
session->callbacks.on_frame_not_send_callback(
session, frame, rv, session->user_data) != 0) {
nghttp2_outbound_item_free(item, mem);
nghttp2_mem_free(mem, item);
@ -3323,8 +3310,8 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session,
}
if (opened_stream_id) {
/* careful not to override rv */
rv2 = nghttp2_session_close_stream(session, opened_stream_id,
error_code);
rv2 =
nghttp2_session_close_stream(session, opened_stream_id, error_code);
}
nghttp2_outbound_item_free(item, mem);
@ -3338,8 +3325,8 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session,
if (rv == NGHTTP2_ERR_HEADER_COMP) {
/* If header compression error occurred, should terminate
connection. */
rv = nghttp2_session_terminate_session(session,
NGHTTP2_INTERNAL_ERROR);
rv =
nghttp2_session_terminate_session(session, NGHTTP2_INTERNAL_ERROR);
}
if (nghttp2_is_fatal(rv)) {
return rv;
@ -3634,7 +3621,6 @@ static int session_call_on_begin_frame(nghttp2_session *session,
int rv;
if (session->callbacks.on_begin_frame_callback) {
rv = session->callbacks.on_begin_frame_callback(session, hd,
session->user_data);
@ -4028,8 +4014,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
return rv;
}
rv = session_handle_invalid_stream2(session,
subject_stream->stream_id,
rv =
session_handle_invalid_stream2(session, subject_stream->stream_id,
frame, NGHTTP2_ERR_HTTP_HEADER);
if (nghttp2_is_fatal(rv)) {
return rv;
@ -4588,7 +4574,6 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
outbound queue. */
if (stream->remote_window_size > 0 &&
nghttp2_stream_check_deferred_by_flow_control(stream)) {
rv = session_resume_deferred_stream_item(
arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
@ -4645,7 +4630,6 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
if (nghttp2_should_send_window_update(stream->local_window_size,
stream->recv_window_size)) {
rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE,
stream->stream_id,
stream->recv_window_size);
@ -5071,8 +5055,7 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
if (stream->shut_flags & NGHTTP2_SHUT_RD) {
return session_inflate_handle_invalid_connection(
session, frame, NGHTTP2_ERR_STREAM_CLOSED,
"PUSH_PROMISE: stream closed");
session, frame, NGHTTP2_ERR_STREAM_CLOSED, "PUSH_PROMISE: stream closed");
}
nghttp2_priority_spec_init(&pri_spec, stream->stream_id,
@ -5233,7 +5216,6 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
if (stream->remote_window_size > 0 &&
nghttp2_stream_check_deferred_by_flow_control(stream)) {
rv = session_resume_deferred_stream_item(
session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
@ -5539,9 +5521,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
stream->window_update_queued == 0 &&
nghttp2_should_send_window_update(stream->local_window_size,
stream->recv_window_size)) {
rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE,
stream->stream_id,
stream->recv_window_size);
rv = nghttp2_session_add_window_update(
session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size);
if (rv != 0) {
return rv;
}
@ -6564,8 +6545,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (padlen < 0 || (size_t)padlen + 4 /* promised stream id */
> 1 + iframe->payloadleft) {
rv = nghttp2_session_terminate_session_with_reason(
session, NGHTTP2_PROTOCOL_ERROR,
"PUSH_PROMISE: invalid padding");
session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: invalid padding");
if (nghttp2_is_fatal(rv)) {
return rv;
}
@ -6816,7 +6796,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if ((iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) == 0) {
inbound_frame_set_mark(iframe, NGHTTP2_FRAME_HDLEN);
iframe->padlen = 0;
@ -7097,8 +7076,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (readlen > 0) {
nghttp2_ssize data_readlen;
rv = nghttp2_session_update_recv_connection_window_size(session,
readlen);
rv =
nghttp2_session_update_recv_connection_window_size(session, readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@ -7115,8 +7094,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
data_readlen = inbound_frame_effective_readlen(
iframe, iframe->payloadleft, readlen);
data_readlen =
inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen);
if (data_readlen == -1) {
/* everything is padding */
@ -7208,8 +7187,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (readlen > 0) {
/* Update connection-level flow control window for ignored
DATA frame too */
rv = nghttp2_session_update_recv_connection_window_size(session,
readlen);
rv =
nghttp2_session_update_recv_connection_window_size(session, readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@ -7219,7 +7198,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
/* Ignored DATA is considered as "consumed" immediately. */
rv = session_update_connection_consumed_size(session, readlen);
@ -7719,20 +7697,20 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
session->callbacks.read_length_callback) {
if (session->callbacks.read_length_callback2) {
payloadlen = session->callbacks.read_length_callback2(
session, frame->hd.type, stream->stream_id,
session->remote_window_size, stream->remote_window_size,
session->remote_settings.max_frame_size, session->user_data);
session, frame->hd.type, stream->stream_id, session->remote_window_size,
stream->remote_window_size, session->remote_settings.max_frame_size,
session->user_data);
} else {
payloadlen = (nghttp2_ssize)session->callbacks.read_length_callback(
session, frame->hd.type, stream->stream_id,
session->remote_window_size, stream->remote_window_size,
session->remote_settings.max_frame_size, session->user_data);
session, frame->hd.type, stream->stream_id, session->remote_window_size,
stream->remote_window_size, session->remote_settings.max_frame_size,
session->user_data);
}
DEBUGF("send: read_length_callback=%td\n", payloadlen);
payloadlen = nghttp2_session_enforce_flow_control_limits(session, stream,
payloadlen);
payloadlen =
nghttp2_session_enforce_flow_control_limits(session, stream, payloadlen);
DEBUGF("send: read_length_callback after flow control=%td\n", payloadlen);
@ -8419,8 +8397,8 @@ void nghttp2_session_set_user_data(nghttp2_session *session, void *user_data) {
}
int nghttp2_session_change_extpri_stream_priority(
nghttp2_session *session, int32_t stream_id,
const nghttp2_extpri *extpri_in, int ignore_client_signal) {
nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri_in,
int ignore_client_signal) {
nghttp2_stream *stream;
nghttp2_extpri extpri = *extpri_in;

View File

@ -124,10 +124,9 @@ typedef enum {
NGHTTP2_HTTP_FLAG_METH_HEAD = 1 << 8,
NGHTTP2_HTTP_FLAG_METH_OPTIONS = 1 << 9,
NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND = 1 << 10,
NGHTTP2_HTTP_FLAG_METH_ALL = NGHTTP2_HTTP_FLAG_METH_CONNECT |
NGHTTP2_HTTP_FLAG_METH_HEAD |
NGHTTP2_HTTP_FLAG_METH_OPTIONS |
NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND,
NGHTTP2_HTTP_FLAG_METH_ALL =
NGHTTP2_HTTP_FLAG_METH_CONNECT | NGHTTP2_HTTP_FLAG_METH_HEAD |
NGHTTP2_HTTP_FLAG_METH_OPTIONS | NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND,
/* :path category */
/* path starts with "/" */
NGHTTP2_HTTP_FLAG_PATH_REGULAR = 1 << 11,

View File

@ -174,9 +174,8 @@ int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
stream_id, NULL, nva, nvlen, NULL,
NULL);
return (int)submit_headers_shared_nva(
session, NGHTTP2_FLAG_END_STREAM, stream_id, NULL, nva, nvlen, NULL, NULL);
}
int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,

View File

@ -1075,21 +1075,20 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) {
void sf_base64decode(sf_vec *dest, const sf_vec *src) {
static const int index_tbl[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1};
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1,
-1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1};
uint8_t *o;
const uint8_t *p, *end;
uint32_t n;