diff --git a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h index 6cf947487bf..bcf5ece79e4 100644 --- a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h +++ b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h @@ -2106,7 +2106,7 @@ NGHTTP3_EXTERN int nghttp3_conn_bind_qpack_streams(nghttp3_conn *conn, * control credit (both stream and connection) of underlying QUIC * connection by that amount. It does not include the amount of data * carried by DATA frame which contains application data (excluding - * any control or QPACK unidirectional streams) . See + * any control or QPACK unidirectional streams). See * :type:`nghttp3_recv_data` to handle those bytes. If |fin| is * nonzero, this is the last data from remote endpoint in this stream. * @@ -2480,8 +2480,6 @@ typedef struct nghttp3_data_reader { * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :macro:`NGHTTP3_ERR_INVALID_ARGUMENT` - * |stream_id| identifies unidirectional stream. * :macro:`NGHTTP3_ERR_CONN_CLOSING` * Connection is shutting down, and no new stream is allowed. * :macro:`NGHTTP3_ERR_STREAM_IN_USE` diff --git a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h index 7f6cb8acffe..4061c155876 100644 --- a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h +++ b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h @@ -31,7 +31,7 @@ * * Version number of the nghttp3 library release. */ -#define NGHTTP3_VERSION "1.6.0" +#define NGHTTP3_VERSION "1.10.1" /** * @macro @@ -41,6 +41,6 @@ * number, 8 bits for minor and 8 bits for patch. Version 1.2.3 * becomes 0x010203. */ -#define NGHTTP3_VERSION_NUM 0x010600 +#define NGHTTP3_VERSION_NUM 0x010a01 #endif /* !defined(NGHTTP3_VERSION_H) */ diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c b/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c index aae075a73cc..57cf744680e 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c @@ -50,6 +50,10 @@ size_t nghttp3_buf_cap(const nghttp3_buf *buf) { return (size_t)(buf->end - buf->begin); } +size_t nghttp3_buf_offset(const nghttp3_buf *buf) { + return (size_t)(buf->pos - buf->begin); +} + void nghttp3_buf_reset(nghttp3_buf *buf) { buf->pos = buf->last = buf->begin; } int nghttp3_buf_reserve(nghttp3_buf *buf, size_t size, const nghttp3_mem *mem) { @@ -87,4 +91,12 @@ void nghttp3_typed_buf_init(nghttp3_typed_buf *tbuf, const nghttp3_buf *buf, nghttp3_buf_type type) { tbuf->buf = *buf; tbuf->type = type; + tbuf->buf.begin = tbuf->buf.pos; +} + +void nghttp3_typed_buf_shared_init(nghttp3_typed_buf *tbuf, + const nghttp3_buf *chunk) { + tbuf->buf = *chunk; + tbuf->type = NGHTTP3_BUF_TYPE_SHARED; + tbuf->buf.begin = tbuf->buf.pos = tbuf->buf.last; } diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_buf.h b/deps/ngtcp2/nghttp3/lib/nghttp3_buf.h index 9fa067de91b..c7abd0d3af7 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_buf.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_buf.h @@ -42,6 +42,12 @@ void nghttp3_buf_wrap_init(nghttp3_buf *buf, uint8_t *src, size_t len); */ size_t nghttp3_buf_cap(const nghttp3_buf *buf); +/* + * nghttp3_buf_offset returns the distance from tbuf->begin to + * tbuf->pos. In other words, it returns buf->pos - buf->begin. + */ +size_t nghttp3_buf_offset(const nghttp3_buf *buf); + int nghttp3_buf_reserve(nghttp3_buf *buf, size_t size, const nghttp3_mem *mem); /* @@ -69,6 +75,13 @@ typedef struct nghttp3_typed_buf { void nghttp3_typed_buf_init(nghttp3_typed_buf *tbuf, const nghttp3_buf *buf, nghttp3_buf_type type); +/* + * nghttp3_typed_buf_shared_init initializes |tbuf| of type + * NGHTTP3_BUF_TYPE_SHARED. + */ +void nghttp3_typed_buf_shared_init(nghttp3_typed_buf *tbuf, + const nghttp3_buf *chunk); + void nghttp3_typed_buf_free(nghttp3_typed_buf *tbuf); #endif /* !defined(NGHTTP3_BUF_H) */ diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c index f70b4f5472d..1eec936a895 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c @@ -39,7 +39,7 @@ dynamic table capacity that QPACK encoder is willing to use. */ #define NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY 4096 -nghttp3_objalloc_def(chunk, nghttp3_chunk, oplent); +nghttp3_objalloc_def(chunk, nghttp3_chunk, oplent) /* * conn_remote_stream_uni returns nonzero if |stream_id| is remote @@ -233,12 +233,16 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version, const nghttp3_callbacks *callbacks, int settings_version, const nghttp3_settings *settings, const nghttp3_mem *mem, void *user_data) { - int rv; nghttp3_conn *conn; size_t i; (void)callbacks_version; (void)settings_version; + assert(settings->max_field_section_size <= NGHTTP3_VARINT_MAX); + assert(settings->qpack_max_dtable_capacity <= NGHTTP3_VARINT_MAX); + assert(settings->qpack_encoder_max_dtable_capacity <= NGHTTP3_VARINT_MAX); + assert(settings->qpack_blocked_streams <= NGHTTP3_VARINT_MAX); + if (mem == NULL) { mem = nghttp3_mem_default(); } @@ -254,18 +258,11 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version, nghttp3_map_init(&conn->streams, mem); - rv = - nghttp3_qpack_decoder_init(&conn->qdec, settings->qpack_max_dtable_capacity, - settings->qpack_blocked_streams, mem); - if (rv != 0) { - goto qdec_init_fail; - } + nghttp3_qpack_decoder_init(&conn->qdec, settings->qpack_max_dtable_capacity, + settings->qpack_blocked_streams, mem); - rv = nghttp3_qpack_encoder_init( - &conn->qenc, settings->qpack_encoder_max_dtable_capacity, mem); - if (rv != 0) { - goto qenc_init_fail; - } + nghttp3_qpack_encoder_init(&conn->qenc, + settings->qpack_encoder_max_dtable_capacity, mem); nghttp3_pq_init(&conn->qpack_blocked_streams, ricnt_less, mem); @@ -291,16 +288,6 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version, *pconn = conn; return 0; - -qenc_init_fail: - nghttp3_qpack_decoder_free(&conn->qdec); -qdec_init_fail: - nghttp3_map_free(&conn->streams); - nghttp3_objalloc_free(&conn->stream_objalloc); - nghttp3_objalloc_free(&conn->out_chunk_objalloc); - nghttp3_mem_free(mem, conn); - - return rv; } int nghttp3_conn_client_new_versioned(nghttp3_conn **pconn, @@ -399,6 +386,9 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id, size_t bidi_nproc; int rv; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + stream = nghttp3_conn_find_stream(conn, stream_id); if (stream == NULL) { /* TODO Assert idtr */ @@ -434,6 +424,10 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id, return rv; } } + } else if (!nghttp3_client_stream_uni(stream_id)) { + /* server does not expect to receive new server initiated + bidirectional or unidirectional stream from client. */ + return NGHTTP3_ERR_H3_STREAM_CREATION_ERROR; } else { /* unidirectional stream */ if (srclen == 0 && fin) { @@ -448,7 +442,7 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id, stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL; stream->tx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL; - } else if (nghttp3_stream_uni(stream_id)) { + } else if (nghttp3_server_stream_uni(stream_id)) { if (srclen == 0 && fin) { return 0; } @@ -461,17 +455,16 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id, stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_INITIAL; stream->tx.hstate = NGHTTP3_HTTP_STATE_RESP_INITIAL; } else { - /* client doesn't expect to receive new bidirectional stream - from server. */ + /* client doesn't expect to receive new bidirectional stream or + client initiated unidirectional stream from server. */ return NGHTTP3_ERR_H3_STREAM_CREATION_ERROR; } } else if (conn->server) { - if (nghttp3_client_stream_bidi(stream_id)) { - if (stream->rx.hstate == NGHTTP3_HTTP_STATE_NONE) { - stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL; - stream->tx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL; - } - } + assert(nghttp3_client_stream_bidi(stream_id) || + nghttp3_client_stream_uni(stream_id)); + } else { + assert(nghttp3_client_stream_bidi(stream_id) || + nghttp3_server_stream_uni(stream_id)); } if (srclen == 0 && !fin) { @@ -608,6 +601,9 @@ nghttp3_ssize nghttp3_conn_read_uni(nghttp3_conn *conn, nghttp3_stream *stream, break; case NGHTTP3_STREAM_TYPE_UNKNOWN: nconsumed = (nghttp3_ssize)srclen; + if (fin) { + break; + } rv = conn_call_stop_sending(conn, stream, NGHTTP3_H3_STREAM_CREATION_ERROR); if (rv != 0) { @@ -665,7 +661,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn, nghttp3_varint_read_state_reset(rvint); rstate->state = NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH; if (p == end) { - break; + return (nghttp3_ssize)nconsumed; } /* Fall through */ case NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH: @@ -973,6 +969,10 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn, rstate->state = NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE; + if (p == end) { + return (nghttp3_ssize)nconsumed; + } + /* Fall through */ case NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE: /* We need to buffer Priority Field Value because it might be @@ -1792,6 +1792,8 @@ conn_on_priority_update_stream(nghttp3_conn *conn, stream->node.pri = fr->pri; stream->flags |= NGHTTP3_STREAM_FLAG_PRIORITY_UPDATE_RECVED; + stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL; + stream->tx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL; return 0; } @@ -1836,7 +1838,7 @@ int nghttp3_conn_create_stream(nghttp3_conn *conn, nghttp3_stream **pstream, nghttp3_stream *stream; int rv; nghttp3_stream_callbacks callbacks = { - conn_stream_acked_data, + .acked_data = conn_stream_acked_data, }; rv = nghttp3_stream_new(&stream, stream_id, &callbacks, @@ -1874,6 +1876,8 @@ int nghttp3_conn_bind_control_stream(nghttp3_conn *conn, int64_t stream_id) { nghttp3_frame_entry frent; int rv; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); assert(!conn->server || nghttp3_server_stream_uni(stream_id)); assert(conn->server || nghttp3_client_stream_uni(stream_id)); @@ -1906,6 +1910,10 @@ int nghttp3_conn_bind_qpack_streams(nghttp3_conn *conn, int64_t qenc_stream_id, nghttp3_stream *stream; int rv; + assert(qenc_stream_id >= 0); + assert(qenc_stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + assert(qdec_stream_id >= 0); + assert(qdec_stream_id <= (int64_t)NGHTTP3_MAX_VARINT); assert(!conn->server || nghttp3_server_stream_uni(qenc_stream_id)); assert(!conn->server || nghttp3_server_stream_uni(qdec_stream_id)); assert(conn->server || nghttp3_client_stream_uni(qenc_stream_id)); @@ -2194,13 +2202,11 @@ int nghttp3_conn_submit_request(nghttp3_conn *conn, int64_t stream_id, assert(!conn->server); assert(conn->tx.qenc); + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); assert(nghttp3_client_stream_bidi(stream_id)); - /* TODO Should we check that stream_id is client stream_id? */ /* TODO Check GOAWAY last stream ID */ - if (nghttp3_stream_uni(stream_id)) { - return NGHTTP3_ERR_INVALID_ARGUMENT; - } if (conn->flags & NGHTTP3_CONN_FLAG_GOAWAY_RECVED) { return NGHTTP3_ERR_CONN_CLOSING; @@ -2454,6 +2460,9 @@ int nghttp3_conn_close_stream(nghttp3_conn *conn, int64_t stream_id, int nghttp3_conn_shutdown_stream_read(nghttp3_conn *conn, int64_t stream_id) { nghttp3_stream *stream; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + if (!nghttp3_client_stream_bidi(stream_id)) { return 0; } @@ -2515,6 +2524,9 @@ uint64_t nghttp3_conn_get_frame_payload_left(nghttp3_conn *conn, nghttp3_stream *stream; int uni = 0; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + if (!nghttp3_client_stream_bidi(stream_id)) { uni = conn_remote_stream_uni(conn, stream_id); if (!uni) { @@ -2542,6 +2554,8 @@ int nghttp3_conn_get_stream_priority_versioned(nghttp3_conn *conn, (void)pri_version; assert(conn->server); + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); if (!nghttp3_client_stream_bidi(stream_id)) { return NGHTTP3_ERR_INVALID_ARGUMENT; @@ -2566,6 +2580,8 @@ int nghttp3_conn_set_client_stream_priority(nghttp3_conn *conn, uint8_t *buf = NULL; assert(!conn->server); + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); if (!nghttp3_client_stream_bidi(stream_id)) { return NGHTTP3_ERR_INVALID_ARGUMENT; @@ -2603,6 +2619,8 @@ int nghttp3_conn_set_server_stream_priority_versioned(nghttp3_conn *conn, assert(conn->server); assert(pri->urgency < NGHTTP3_URGENCY_LEVELS); assert(pri->inc == 0 || pri->inc == 1); + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); if (!nghttp3_client_stream_bidi(stream_id)) { return NGHTTP3_ERR_INVALID_ARGUMENT; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.h b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.h index 1218ba508ba..3ab6d34422f 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.h @@ -76,7 +76,7 @@ typedef struct nghttp3_chunk { nghttp3_opl_entry oplent; } nghttp3_chunk; -nghttp3_objalloc_decl(chunk, nghttp3_chunk, oplent); +nghttp3_objalloc_decl(chunk, nghttp3_chunk, oplent) struct nghttp3_conn { nghttp3_objalloc out_chunk_objalloc; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_conv.c b/deps/ngtcp2/nghttp3/lib/nghttp3_conv.c index 6439a6d7829..9b32ca3f405 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_conv.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_conv.c @@ -66,8 +66,6 @@ const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p) { } } -int64_t nghttp3_get_varint_fb(const uint8_t *p) { return *p & 0x3f; } - size_t nghttp3_get_varintlen(const uint8_t *p) { return (size_t)(1u << (*p >> 6)); } diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_conv.h b/deps/ngtcp2/nghttp3/lib/nghttp3_conv.h index 40f5d4de782..f70802ce600 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_conv.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_conv.h @@ -135,12 +135,6 @@ STIN uint16_t ntohs(uint16_t netshort) { */ const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p); -/* - * nghttp3_get_varint_fb reads first byte of encoded variable-length - * integer from |p|. - */ -int64_t nghttp3_get_varint_fb(const uint8_t *p); - /* * nghttp3_get_varintlen returns the required number of bytes to read * variable-length integer starting at |p|. diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_gaptr.c b/deps/ngtcp2/nghttp3/lib/nghttp3_gaptr.c index 20eed5faa2b..e8ab509c8f9 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_gaptr.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_gaptr.c @@ -29,14 +29,16 @@ #include void nghttp3_gaptr_init(nghttp3_gaptr *gaptr, const nghttp3_mem *mem) { - nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar, sizeof(nghttp3_range), - mem); + nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar, + nghttp3_ksl_range_search, sizeof(nghttp3_range), mem); gaptr->mem = mem; } static int gaptr_gap_init(nghttp3_gaptr *gaptr) { - nghttp3_range range = {0, UINT64_MAX}; + nghttp3_range range = { + .end = UINT64_MAX, + }; return nghttp3_ksl_insert(&gaptr->gap, NULL, &range, NULL); } @@ -52,7 +54,11 @@ void nghttp3_gaptr_free(nghttp3_gaptr *gaptr) { int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset, uint64_t datalen) { int rv; - nghttp3_range k, m, l, r, q = {offset, offset + datalen}; + nghttp3_range k, m, l, r; + nghttp3_range q = { + .begin = offset, + .end = offset + datalen, + }; nghttp3_ksl_it it; if (nghttp3_ksl_len(&gaptr->gap) == 0) { @@ -62,8 +68,8 @@ int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset, } } - it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q, - nghttp3_ksl_range_exclusive_compar); + it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q, + nghttp3_ksl_range_exclusive_search); for (; !nghttp3_ksl_it_end(&it);) { k = *(nghttp3_range *)nghttp3_ksl_it_key(&it); @@ -112,7 +118,10 @@ uint64_t nghttp3_gaptr_first_gap_offset(nghttp3_gaptr *gaptr) { nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr, uint64_t offset) { - nghttp3_range q = {offset, offset + 1}; + nghttp3_range q = { + .begin = offset, + .end = offset + 1, + }; nghttp3_ksl_it it; if (nghttp3_ksl_len(&gaptr->gap) == 0) { @@ -120,8 +129,8 @@ nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr, return r; } - it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q, - nghttp3_ksl_range_exclusive_compar); + it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q, + nghttp3_ksl_range_exclusive_search); assert(!nghttp3_ksl_it_end(&it)); @@ -130,7 +139,10 @@ nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr, int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset, uint64_t datalen) { - nghttp3_range q = {offset, offset + datalen}; + nghttp3_range q = { + .begin = offset, + .end = offset + datalen, + }; nghttp3_ksl_it it; nghttp3_range m; @@ -138,8 +150,11 @@ int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset, return 0; } - it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q, - nghttp3_ksl_range_exclusive_compar); + it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q, + nghttp3_ksl_range_exclusive_search); + + assert(!nghttp3_ksl_it_end(&it)); + m = nghttp3_range_intersect(&q, (nghttp3_range *)nghttp3_ksl_it_key(&it)); return nghttp3_range_len(&m) == 0; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_http.c b/deps/ngtcp2/nghttp3/lib/nghttp3_http.c index 38092cfb7c3..9a8f06ea11d 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_http.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_http.c @@ -69,11 +69,11 @@ static int64_t parse_uint(const uint8_t *s, size_t len) { } for (i = 0; i < len; ++i) { if ('0' <= s[i] && s[i] <= '9') { - if (n > INT64_MAX / 10) { + if (n > (int64_t)NGHTTP3_MAX_VARINT / 10) { return -1; } n *= 10; - if (n > INT64_MAX - (s[i] - '0')) { + if (n > (int64_t)NGHTTP3_MAX_VARINT - (s[i] - '0')) { return -1; } n += s[i] - '0'; @@ -124,17 +124,17 @@ static int is_ws(uint8_t c) { int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value, size_t valuelen) { nghttp3_pri pri = *dest; - sf_parser sfp; - sf_vec key; - sf_value val; + sfparse_parser sfp; + sfparse_vec key; + sfparse_value val; int rv; - sf_parser_init(&sfp, value, valuelen); + sfparse_parser_init(&sfp, value, valuelen); for (;;) { - rv = sf_parser_dict(&sfp, &key, &val); + rv = sfparse_parser_dict(&sfp, &key, &val); if (rv != 0) { - if (rv == SF_ERR_EOF) { + if (rv == SFPARSE_ERR_EOF) { break; } @@ -147,7 +147,7 @@ int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value, switch (key.base[0]) { case 'i': - if (val.type != SF_TYPE_BOOLEAN) { + if (val.type != SFPARSE_TYPE_BOOLEAN) { return NGHTTP3_ERR_INVALID_ARGUMENT; } @@ -155,7 +155,8 @@ int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value, break; case 'u': - if (val.type != SF_TYPE_INTEGER || val.integer < NGHTTP3_URGENCY_HIGH || + if (val.type != SFPARSE_TYPE_INTEGER || + val.integer < NGHTTP3_URGENCY_HIGH || NGHTTP3_URGENCY_LOW < val.integer) { return NGHTTP3_ERR_INVALID_ARGUMENT; } @@ -197,7 +198,7 @@ static char VALID_AUTHORITY_CHARS[] = { 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 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 */, @@ -548,6 +549,9 @@ static int http_request_on_header(nghttp3_http_state *http, break; case NGHTTP3_QPACK_TOKEN_PRIORITY: if (!nghttp3_check_header_value(nv->value->base, nv->value->len)) { + http->flags &= ~NGHTTP3_HTTP_FLAG_PRIORITY; + http->flags |= NGHTTP3_HTTP_FLAG_BAD_PRIORITY; + return NGHTTP3_ERR_REMOVE_HTTP_HEADER; } @@ -991,7 +995,11 @@ int nghttp3_check_header_value(const uint8_t *value, size_t len) { case 0: return 1; case 1: - return !is_ws(*value); + if (is_ws(*value)) { + return 0; + } + + break; default: if (is_ws(*value) || is_ws(*(value + len - 1))) { return 0; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.c b/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.c index a3b5fbcb05f..33dec06388a 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.c @@ -34,9 +34,9 @@ #include "nghttp3_mem.h" #include "nghttp3_range.h" -static nghttp3_ksl_blk null_blk = {{{NULL, NULL, 0, 0, {0}}}}; +static nghttp3_ksl_blk null_blk; -nghttp3_objalloc_def(ksl_blk, nghttp3_ksl_blk, oplent); +nghttp3_objalloc_def(ksl_blk, nghttp3_ksl_blk, oplent) static size_t ksl_nodelen(size_t keylen) { assert(keylen >= sizeof(uint64_t)); @@ -59,7 +59,8 @@ static void ksl_node_set_key(nghttp3_ksl *ksl, nghttp3_ksl_node *node, } void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar, - size_t keylen, const nghttp3_mem *mem) { + nghttp3_ksl_search search, size_t keylen, + const nghttp3_mem *mem) { size_t nodelen = ksl_nodelen(keylen); nghttp3_objalloc_init(&ksl->blkalloc, @@ -68,6 +69,7 @@ void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar, ksl->head = NULL; ksl->front = ksl->back = NULL; ksl->compar = compar; + ksl->search = search; ksl->n = 0; ksl->keylen = keylen; ksl->nodelen = nodelen; @@ -274,20 +276,6 @@ static void ksl_insert_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i, ++blk->n; } -static size_t ksl_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, - const nghttp3_ksl_key *key, - nghttp3_ksl_compar compar) { - size_t i; - nghttp3_ksl_node *node; - - for (i = 0, node = (nghttp3_ksl_node *)(void *)blk->nodes; - i < blk->n && compar((nghttp3_ksl_key *)node->key, key); - ++i, node = (nghttp3_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen)) - ; - - return i; -} - int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it, const nghttp3_ksl_key *key, void *data) { nghttp3_ksl_blk *blk; @@ -312,7 +300,7 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it, blk = ksl->head; for (;;) { - i = ksl_search(ksl, blk, key, ksl->compar); + i = ksl->search(ksl, blk, key); if (blk->leaf) { if (i < blk->n && @@ -571,7 +559,7 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it, } for (;;) { - i = ksl_search(ksl, blk, key, ksl->compar); + i = ksl->search(ksl, blk, key); if (i == blk->n) { if (it) { @@ -642,12 +630,12 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it, nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl, const nghttp3_ksl_key *key) { - return nghttp3_ksl_lower_bound_compar(ksl, key, ksl->compar); + return nghttp3_ksl_lower_bound_search(ksl, key, ksl->search); } -nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl, +nghttp3_ksl_it nghttp3_ksl_lower_bound_search(const nghttp3_ksl *ksl, const nghttp3_ksl_key *key, - nghttp3_ksl_compar compar) { + nghttp3_ksl_search search) { nghttp3_ksl_blk *blk = ksl->head; nghttp3_ksl_it it; size_t i; @@ -658,7 +646,7 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl, } for (;;) { - i = ksl_search(ksl, blk, key, compar); + i = search(ksl, blk, key); if (blk->leaf) { if (i == blk->n && blk->next) { @@ -702,7 +690,7 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key, assert(ksl->head); for (;;) { - i = ksl_search(ksl, blk, old_key, ksl->compar); + i = ksl->search(ksl, blk, old_key); assert(i < blk->n); node = nghttp3_ksl_nth_node(ksl, blk, i); @@ -825,9 +813,50 @@ int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs, return a->begin < b->begin; } +nghttp3_ksl_search_def(range, nghttp3_ksl_range_compar) + +size_t nghttp3_ksl_range_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key) { + return ksl_range_search(ksl, blk, key); +} + int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs, const nghttp3_ksl_key *rhs) { const nghttp3_range *a = lhs, *b = rhs; return a->begin < b->begin && !(nghttp3_max_uint64(a->begin, b->begin) < nghttp3_min_uint64(a->end, b->end)); } + +nghttp3_ksl_search_def(range_exclusive, nghttp3_ksl_range_exclusive_compar) + +size_t nghttp3_ksl_range_exclusive_search(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key) { + return ksl_range_exclusive_search(ksl, blk, key); +} + +int nghttp3_ksl_uint64_less(const nghttp3_ksl_key *lhs, + const nghttp3_ksl_key *rhs) { + return *(uint64_t *)lhs < *(uint64_t *)rhs; +} + +nghttp3_ksl_search_def(uint64_less, nghttp3_ksl_uint64_less) + +size_t nghttp3_ksl_uint64_less_search(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key) { + return ksl_uint64_less_search(ksl, blk, key); +} + +int nghttp3_ksl_int64_greater(const nghttp3_ksl_key *lhs, + const nghttp3_ksl_key *rhs) { + return *(int64_t *)lhs > *(int64_t *)rhs; +} + +nghttp3_ksl_search_def(int64_greater, nghttp3_ksl_int64_greater) + +size_t nghttp3_ksl_int64_greater_search(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key) { + return ksl_int64_greater_search(ksl, blk, key); +} diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.h b/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.h index e15e227ce50..d0ce8cd664d 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_ksl.h @@ -104,7 +104,7 @@ struct nghttp3_ksl_blk { }; }; -nghttp3_objalloc_decl(ksl_blk, nghttp3_ksl_blk, oplent); +nghttp3_objalloc_decl(ksl_blk, nghttp3_ksl_blk, oplent) /* * nghttp3_ksl_compar is a function type which returns nonzero if key @@ -115,6 +115,35 @@ typedef int (*nghttp3_ksl_compar)(const nghttp3_ksl_key *lhs, typedef struct nghttp3_ksl nghttp3_ksl; +/* + * nghttp3_ksl_search is a function to search for the first element in + * |blk|->nodes which is not ordered before |key|. It returns the + * index of such element. It returns |blk|->n if there is no such + * element. + */ +typedef size_t (*nghttp3_ksl_search)(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key); + +/* + * nghttp3_ksl_search_def is a macro to implement nghttp3_ksl_search + * with COMPAR which is supposed to be nghttp3_ksl_compar. + */ +#define nghttp3_ksl_search_def(NAME, COMPAR) \ + static size_t ksl_##NAME##_search(const nghttp3_ksl *ksl, \ + nghttp3_ksl_blk *blk, \ + const nghttp3_ksl_key *key) { \ + size_t i; \ + nghttp3_ksl_node *node; \ + \ + for (i = 0, node = (nghttp3_ksl_node *)(void *)blk->nodes; \ + i < blk->n && COMPAR((nghttp3_ksl_key *)node->key, key); ++i, \ + node = (nghttp3_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen)) \ + ; \ + \ + return i; \ + } + typedef struct nghttp3_ksl_it nghttp3_ksl_it; /* @@ -138,6 +167,7 @@ struct nghttp3_ksl { /* back points to the last leaf block. */ nghttp3_ksl_blk *back; nghttp3_ksl_compar compar; + nghttp3_ksl_search search; /* n is the number of elements stored. */ size_t n; /* keylen is the size of key */ @@ -149,11 +179,13 @@ struct nghttp3_ksl { /* * nghttp3_ksl_init initializes |ksl|. |compar| specifies compare - * function. |keylen| is the length of key and must be at least + * function. |search| is a search function which must use |compar|. + * |keylen| is the length of key and must be at least * sizeof(uint64_t). */ void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar, - size_t keylen, const nghttp3_mem *mem); + nghttp3_ksl_search search, size_t keylen, + const nghttp3_mem *mem); /* * nghttp3_ksl_free frees resources allocated for |ksl|. If |ksl| is @@ -218,12 +250,12 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl, const nghttp3_ksl_key *key); /* - * nghttp3_ksl_lower_bound_compar works like nghttp3_ksl_lower_bound, - * but it takes custom function |compar| to do lower bound search. + * nghttp3_ksl_lower_bound_search works like nghttp3_ksl_lower_bound, + * but it takes custom function |search| to do lower bound search. */ -nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl, +nghttp3_ksl_it nghttp3_ksl_lower_bound_search(const nghttp3_ksl *ksl, const nghttp3_ksl_key *key, - nghttp3_ksl_compar compar); + nghttp3_ksl_search search); /* * nghttp3_ksl_update_key replaces the key of nodes which has @@ -330,22 +362,69 @@ int nghttp3_ksl_it_begin(const nghttp3_ksl_it *it); /* * nghttp3_ksl_range_compar is an implementation of - * nghttp3_ksl_compar. lhs->ptr and rhs->ptr must point to - * nghttp3_range object and the function returns nonzero if (const - * nghttp3_range *)(lhs->ptr)->begin < (const nghttp3_range - * *)(rhs->ptr)->begin. + * nghttp3_ksl_compar. |lhs| and |rhs| must point to nghttp3_range + * object, and the function returns nonzero if ((const nghttp3_range + * *)lhs)->begin < ((const nghttp3_range *)rhs)->begin. */ int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs, const nghttp3_ksl_key *rhs); +/* + * nghttp3_ksl_range_search is an implementation of nghttp3_ksl_search + * that uses nghttp3_ksl_range_compar. + */ +size_t nghttp3_ksl_range_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key); + /* * nghttp3_ksl_range_exclusive_compar is an implementation of - * nghttp3_ksl_compar. lhs->ptr and rhs->ptr must point to - * nghttp3_range object and the function returns nonzero if (const - * nghttp3_range *)(lhs->ptr)->begin < (const nghttp3_range - * *)(rhs->ptr)->begin and the 2 ranges do not intersect. + * nghttp3_ksl_compar. |lhs| and |rhs| must point to nghttp3_range + * object, and the function returns nonzero if ((const nghttp3_range + * *)lhs)->begin < ((const nghttp3_range *)rhs)->begin, and the 2 + * ranges do not intersect. */ int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs, const nghttp3_ksl_key *rhs); +/* + * nghttp3_ksl_range_exclusive_search is an implementation of + * nghttp3_ksl_search that uses nghttp3_ksl_range_exclusive_compar. + */ +size_t nghttp3_ksl_range_exclusive_search(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key); + +/* + * nghttp3_ksl_uint64_less is an implementation of nghttp3_ksl_compar. + * |lhs| and |rhs| must point to uint64_t objects, and the function + * returns nonzero if *(uint64_t *)|lhs| < *(uint64_t *)|rhs|. + */ +int nghttp3_ksl_uint64_less(const nghttp3_ksl_key *lhs, + const nghttp3_ksl_key *rhs); + +/* + * nghttp3_ksl_uint64_less_search is an implementation of + * nghttp3_ksl_search that uses nghttp3_ksl_uint64_less. + */ +size_t nghttp3_ksl_uint64_less_search(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key); + +/* + * nghttp3_ksl_int64_greater is an implementation of + * nghttp3_ksl_compar. |lhs| and |rhs| must point to int64_t objects, + * and the function returns nonzero if *(int64_t *)|lhs| > *(int64_t + * *)|rhs|. + */ +int nghttp3_ksl_int64_greater(const nghttp3_ksl_key *lhs, + const nghttp3_ksl_key *rhs); + +/* + * nghttp3_ksl_int64_greater_search is an implementation of + * nghttp3_ksl_search that uses nghttp3_ksl_int64_greater. + */ +size_t nghttp3_ksl_int64_greater_search(const nghttp3_ksl *ksl, + nghttp3_ksl_blk *blk, + const nghttp3_ksl_key *key); + #endif /* !defined(NGHTTP3_KSL_H) */ diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_macro.h b/deps/ngtcp2/nghttp3/lib/nghttp3_macro.h index a4e1dfea3cd..ffe0ea70924 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_macro.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_macro.h @@ -48,27 +48,27 @@ #define nghttp3_max_def(SUFFIX, T) \ static inline T nghttp3_max_##SUFFIX(T a, T b) { return a < b ? b : a; } -nghttp3_max_def(int8, int8_t); -nghttp3_max_def(int16, int16_t); -nghttp3_max_def(int32, int32_t); -nghttp3_max_def(int64, int64_t); -nghttp3_max_def(uint8, uint8_t); -nghttp3_max_def(uint16, uint16_t); -nghttp3_max_def(uint32, uint32_t); -nghttp3_max_def(uint64, uint64_t); -nghttp3_max_def(size, size_t); +nghttp3_max_def(int8, int8_t) +nghttp3_max_def(int16, int16_t) +nghttp3_max_def(int32, int32_t) +nghttp3_max_def(int64, int64_t) +nghttp3_max_def(uint8, uint8_t) +nghttp3_max_def(uint16, uint16_t) +nghttp3_max_def(uint32, uint32_t) +nghttp3_max_def(uint64, uint64_t) +nghttp3_max_def(size, size_t) #define nghttp3_min_def(SUFFIX, T) \ static inline T nghttp3_min_##SUFFIX(T a, T b) { return a < b ? a : b; } -nghttp3_min_def(int8, int8_t); -nghttp3_min_def(int16, int16_t); -nghttp3_min_def(int32, int32_t); -nghttp3_min_def(int64, int64_t); -nghttp3_min_def(uint8, uint8_t); -nghttp3_min_def(uint16, uint16_t); -nghttp3_min_def(uint32, uint32_t); -nghttp3_min_def(uint64, uint64_t); -nghttp3_min_def(size, size_t); +nghttp3_min_def(int8, int8_t) +nghttp3_min_def(int16, int16_t) +nghttp3_min_def(int32, int32_t) +nghttp3_min_def(int64, int64_t) +nghttp3_min_def(uint8, uint8_t) +nghttp3_min_def(uint16, uint16_t) +nghttp3_min_def(uint32, uint32_t) +nghttp3_min_def(uint64, uint64_t) +nghttp3_min_def(size, size_t) #endif /* !defined(NGHTTP3_MACRO_H) */ diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_map.c b/deps/ngtcp2/nghttp3/lib/nghttp3_map.c index cc5e42a2caf..829f9e83eeb 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_map.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_map.c @@ -120,7 +120,11 @@ void nghttp3_map_print_distance(const nghttp3_map *map) { static int insert(nghttp3_map_bucket *table, size_t hashbits, nghttp3_map_key_type key, void *data) { size_t idx = hash(key, hashbits); - nghttp3_map_bucket b = {0, key, data}, *bkt; + nghttp3_map_bucket b = { + .key = key, + .data = data, + }; + nghttp3_map_bucket *bkt; size_t mask = (1u << hashbits) - 1; for (;;) { diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_pq.c b/deps/ngtcp2/nghttp3/lib/nghttp3_pq.c index feefcd6fc71..e35bcac4e43 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_pq.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_pq.c @@ -164,20 +164,4 @@ int nghttp3_pq_empty(const nghttp3_pq *pq) { return pq->length == 0; } size_t nghttp3_pq_size(const nghttp3_pq *pq) { return pq->length; } -int nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg) { - size_t i; - - if (pq->length == 0) { - return 0; - } - - for (i = 0; i < pq->length; ++i) { - if ((*fun)(pq->q[i], arg)) { - return 1; - } - } - - return 0; -} - void nghttp3_pq_clear(nghttp3_pq *pq) { pq->length = 0; } diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_pq.h b/deps/ngtcp2/nghttp3/lib/nghttp3_pq.h index 3813b529473..c4e47b16708 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_pq.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_pq.h @@ -112,17 +112,6 @@ int nghttp3_pq_empty(const nghttp3_pq *pq); */ size_t nghttp3_pq_size(const nghttp3_pq *pq); -typedef int (*nghttp3_pq_item_cb)(nghttp3_pq_entry *item, void *arg); - -/* - * nghttp3_pq_each applies |fun| to each item in |pq|. The |arg| is - * passed as arg parameter to callback function. This function must - * not change the ordering key. If the return value from callback is - * nonzero, this function returns 1 immediately without iterating - * remaining items. Otherwise this function returns 0. - */ -int nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg); - /* * nghttp3_pq_remove removes |item| from |pq|. |pq| must contain * |item| otherwise the behavior is undefined. diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c index a1c7e7487c1..c41fc53b8f5 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c @@ -41,7 +41,12 @@ #define NGHTTP3_QPACK_MAX_QPACK_STREAMS 2000 /* Make scalar initialization form of nghttp3_qpack_static_entry */ -#define MAKE_STATIC_ENT(I, T, H) {I, T, H} +#define MAKE_STATIC_ENT(I, T, H) \ + { \ + .absidx = I, \ + .token = T, \ + .hash = H, \ + } /* Generated by mkstatichdtbl.py */ static nghttp3_qpack_static_entry token_stable[] = { @@ -166,9 +171,19 @@ static nghttp3_qpack_static_entry token_stable[] = { /* Make scalar initialization form of nghttp3_qpack_static_entry */ #define MAKE_STATIC_HD(N, V, T) \ { \ - {NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \ - {NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \ - T, \ + .name = \ + { \ + .base = (uint8_t *)(N), \ + .len = sizeof((N)) - 1, \ + .ref = -1, \ + }, \ + .value = \ + { \ + .base = (uint8_t *)(V), \ + .len = sizeof((V)) - 1, \ + .ref = -1, \ + }, \ + .token = T, \ } static nghttp3_qpack_static_header stable[] = { @@ -828,29 +843,12 @@ static void encoder_qpack_map_find(nghttp3_qpack_encoder *encoder, * ctx->max_dtable_capacity and it is initialized to 0. * |hard_max_dtable_capacity| is the upper bound of * ctx->max_dtable_capacity. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP3_ERR_NOMEM - * Out of memory. */ -static int qpack_context_init(nghttp3_qpack_context *ctx, - size_t hard_max_dtable_capacity, - size_t max_blocked_streams, - const nghttp3_mem *mem) { - int rv; - size_t len = 4096 / NGHTTP3_QPACK_ENTRY_OVERHEAD; - size_t len2; - - for (len2 = 1; len2 < len; len2 <<= 1) - ; - - rv = nghttp3_ringbuf_init(&ctx->dtable, len2, sizeof(nghttp3_qpack_entry *), - mem); - if (rv != 0) { - return rv; - } +static void qpack_context_init(nghttp3_qpack_context *ctx, + size_t hard_max_dtable_capacity, + size_t max_blocked_streams, + const nghttp3_mem *mem) { + nghttp3_ringbuf_init(&ctx->dtable, 0, sizeof(nghttp3_qpack_entry *), mem); ctx->mem = mem; ctx->dtable_size = 0; @@ -860,8 +858,6 @@ static int qpack_context_init(nghttp3_qpack_context *ctx, ctx->max_blocked_streams = max_blocked_streams; ctx->next_absidx = 0; ctx->bad = 0; - - return 0; } static void qpack_context_free(nghttp3_qpack_context *ctx) { @@ -898,19 +894,17 @@ static int max_cnt_greater(const nghttp3_ksl_key *lhs, return a->max_cnt > b->max_cnt || (a->max_cnt == b->max_cnt && a->id < b->id); } -int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder, - size_t hard_max_dtable_capacity, - const nghttp3_mem *mem) { - int rv; +nghttp3_ksl_search_def(max_cnt_greater, max_cnt_greater) - rv = qpack_context_init(&encoder->ctx, hard_max_dtable_capacity, 0, mem); - if (rv != 0) { - return rv; - } +void nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder, + size_t hard_max_dtable_capacity, + const nghttp3_mem *mem) { + qpack_context_init(&encoder->ctx, hard_max_dtable_capacity, 0, mem); nghttp3_map_init(&encoder->streams, mem); nghttp3_ksl_init(&encoder->blocked_streams, max_cnt_greater, + ksl_max_cnt_greater_search, sizeof(nghttp3_blocked_streams_key), mem); qpack_map_init(&encoder->dtable_map); @@ -925,8 +919,6 @@ int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder, encoder->flags = NGHTTP3_QPACK_ENCODER_FLAG_NONE; nghttp3_qpack_read_state_reset(&encoder->rstate); - - return 0; } static int map_stream_free(void *data, void *ptr) { @@ -1149,6 +1141,9 @@ int nghttp3_qpack_encoder_encode(nghttp3_qpack_encoder *encoder, int blocked_stream; nghttp3_qpack_stream *stream; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + if (encoder->ctx.bad) { return NGHTTP3_ERR_QPACK_FATAL; } @@ -1444,7 +1439,14 @@ int nghttp3_qpack_encoder_encode_nv(nghttp3_qpack_encoder *encoder, uint32_t hash = 0; int32_t token; nghttp3_qpack_indexing_mode indexing_mode; - nghttp3_qpack_lookup_result sres = {-1, 0, -1}, dres = {-1, 0, -1}; + nghttp3_qpack_lookup_result sres = { + .index = -1, + .pb_index = -1, + }; + nghttp3_qpack_lookup_result dres = { + .index = -1, + .pb_index = -1, + }; nghttp3_qpack_entry *new_ent = NULL; int static_entry; int just_index = 0; @@ -1608,8 +1610,10 @@ int nghttp3_qpack_encoder_encode_nv(nghttp3_qpack_encoder *encoder, nghttp3_qpack_lookup_result nghttp3_qpack_lookup_stable(const nghttp3_nv *nv, int32_t token, nghttp3_qpack_indexing_mode indexing_mode) { - nghttp3_qpack_lookup_result res = {(nghttp3_ssize)token_stable[token].absidx, - 0, -1}; + nghttp3_qpack_lookup_result res = { + .index = (nghttp3_ssize)token_stable[token].absidx, + .pb_index = -1, + }; nghttp3_qpack_static_entry *ent; nghttp3_qpack_static_header *hdr; size_t i; @@ -1639,7 +1643,10 @@ nghttp3_qpack_lookup_result nghttp3_qpack_encoder_lookup_dtable( nghttp3_qpack_encoder *encoder, const nghttp3_nv *nv, int32_t token, uint32_t hash, nghttp3_qpack_indexing_mode indexing_mode, uint64_t krcnt, int allow_blocking) { - nghttp3_qpack_lookup_result res = {-1, 0, -1}; + nghttp3_qpack_lookup_result res = { + .index = -1, + .pb_index = -1, + }; int exact_match = 0; nghttp3_qpack_entry *match, *pb_match; @@ -1694,7 +1701,6 @@ static int ref_max_cnt_greater(const nghttp3_pq_entry *lhsx, int nghttp3_qpack_stream_new(nghttp3_qpack_stream **pstream, int64_t stream_id, const nghttp3_mem *mem) { - int rv; nghttp3_qpack_stream *stream; stream = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_stream)); @@ -1702,12 +1708,8 @@ int nghttp3_qpack_stream_new(nghttp3_qpack_stream **pstream, int64_t stream_id, return NGHTTP3_ERR_NOMEM; } - rv = nghttp3_ringbuf_init(&stream->refs, 4, - sizeof(nghttp3_qpack_header_block_ref *), mem); - if (rv != 0) { - nghttp3_mem_free(mem, stream); - return rv; - } + nghttp3_ringbuf_init(&stream->refs, 0, + sizeof(nghttp3_qpack_header_block_ref *), mem); nghttp3_pq_init(&stream->max_cnts, ref_max_cnt_greater, mem); @@ -1759,17 +1761,23 @@ int nghttp3_qpack_stream_add_ref(nghttp3_qpack_stream *stream, int rv; if (nghttp3_ringbuf_full(&stream->refs)) { - rv = nghttp3_ringbuf_reserve(&stream->refs, - nghttp3_ringbuf_len(&stream->refs) * 2); + rv = nghttp3_ringbuf_reserve( + &stream->refs, + nghttp3_max_size(4, nghttp3_ringbuf_len(&stream->refs) * 2)); if (rv != 0) { return rv; } } + rv = nghttp3_pq_push(&stream->max_cnts, &ref->max_cnts_pe); + if (rv != 0) { + return rv; + } + dest = nghttp3_ringbuf_push_back(&stream->refs); *dest = ref; - return nghttp3_pq_push(&stream->max_cnts, &ref->max_cnts_pe); + return 0; } void nghttp3_qpack_stream_pop_ref(nghttp3_qpack_stream *stream) { @@ -1834,7 +1842,7 @@ static int qpack_encoder_write_indexed_name(nghttp3_qpack_encoder *encoder, int h = 0; hlen = nghttp3_qpack_huffman_encode_count(nv->value, nv->valuelen); - if (hlen * 4 < nv->valuelen * 3) { + if (hlen < nv->valuelen) { h = 1; len += nghttp3_qpack_put_varint_len(hlen, 7) + hlen; } else { @@ -1925,7 +1933,7 @@ static int qpack_encoder_write_literal(nghttp3_qpack_encoder *encoder, int nh = 0, vh = 0; nhlen = nghttp3_qpack_huffman_encode_count(nv->name, nv->namelen); - if (nhlen * 4 < nv->namelen * 3) { + if (nhlen < nv->namelen) { nh = 1; len = nghttp3_qpack_put_varint_len(nhlen, prefix) + nhlen; } else { @@ -1933,7 +1941,7 @@ static int qpack_encoder_write_literal(nghttp3_qpack_encoder *encoder, } vhlen = nghttp3_qpack_huffman_encode_count(nv->value, nv->valuelen); - if (vhlen * 4 < nv->valuelen * 3) { + if (vhlen < nv->valuelen) { vh = 1; len += nghttp3_qpack_put_varint_len(vhlen, 7) + vhlen; } else { @@ -2083,8 +2091,9 @@ int nghttp3_qpack_context_dtable_add(nghttp3_qpack_context *ctx, hash); if (nghttp3_ringbuf_full(&ctx->dtable)) { - rv = nghttp3_ringbuf_reserve(&ctx->dtable, - nghttp3_ringbuf_len(&ctx->dtable) * 2); + rv = nghttp3_ringbuf_reserve( + &ctx->dtable, + nghttp3_max_size(128, nghttp3_ringbuf_len(&ctx->dtable) * 2)); if (rv != 0) { goto fail; } @@ -2259,10 +2268,11 @@ void nghttp3_qpack_entry_free(nghttp3_qpack_entry *ent) { int nghttp3_qpack_encoder_block_stream(nghttp3_qpack_encoder *encoder, nghttp3_qpack_stream *stream) { nghttp3_blocked_streams_key bsk = { - nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts), - nghttp3_qpack_header_block_ref, max_cnts_pe) - ->max_cnt, - (uint64_t)stream->stream_id}; + .max_cnt = nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts), + nghttp3_qpack_header_block_ref, max_cnts_pe) + ->max_cnt, + .id = (uint64_t)stream->stream_id, + }; return nghttp3_ksl_insert(&encoder->blocked_streams, NULL, &bsk, stream); } @@ -2270,10 +2280,11 @@ int nghttp3_qpack_encoder_block_stream(nghttp3_qpack_encoder *encoder, void nghttp3_qpack_encoder_unblock_stream(nghttp3_qpack_encoder *encoder, nghttp3_qpack_stream *stream) { nghttp3_blocked_streams_key bsk = { - nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts), - nghttp3_qpack_header_block_ref, max_cnts_pe) - ->max_cnt, - (uint64_t)stream->stream_id}; + .max_cnt = nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts), + nghttp3_qpack_header_block_ref, max_cnts_pe) + ->max_cnt, + .id = (uint64_t)stream->stream_id, + }; nghttp3_ksl_it it; /* This is purely debugging purpose only */ @@ -2287,7 +2298,9 @@ void nghttp3_qpack_encoder_unblock_stream(nghttp3_qpack_encoder *encoder, void nghttp3_qpack_encoder_unblock(nghttp3_qpack_encoder *encoder, uint64_t max_cnt) { - nghttp3_blocked_streams_key bsk = {max_cnt, 0}; + nghttp3_blocked_streams_key bsk = { + .max_cnt = max_cnt, + }; nghttp3_ksl_it it; it = nghttp3_ksl_lower_bound(&encoder->blocked_streams, &bsk); @@ -2667,17 +2680,12 @@ void nghttp3_qpack_read_state_reset(nghttp3_qpack_read_state *rstate) { rstate->huffman_encoded = 0; } -int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder, - size_t hard_max_dtable_capacity, - size_t max_blocked_streams, - const nghttp3_mem *mem) { - int rv; - - rv = qpack_context_init(&decoder->ctx, hard_max_dtable_capacity, - max_blocked_streams, mem); - if (rv != 0) { - return rv; - } +void nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder, + size_t hard_max_dtable_capacity, + size_t max_blocked_streams, + const nghttp3_mem *mem) { + qpack_context_init(&decoder->ctx, hard_max_dtable_capacity, + max_blocked_streams, mem); decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE; decoder->opcode = 0; @@ -2687,8 +2695,6 @@ int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder, nghttp3_qpack_read_state_reset(&decoder->rstate); nghttp3_buf_init(&decoder->dbuf); - - return 0; } void nghttp3_qpack_decoder_free(nghttp3_qpack_decoder *decoder) { @@ -3171,6 +3177,7 @@ int nghttp3_qpack_decoder_dtable_static_add(nghttp3_qpack_decoder *decoder) { rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0); nghttp3_rcbuf_decref(qnv.value); + decoder->rstate.value = NULL; return rv; } @@ -3197,6 +3204,7 @@ int nghttp3_qpack_decoder_dtable_dynamic_add(nghttp3_qpack_decoder *decoder) { rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0); nghttp3_rcbuf_decref(qnv.value); + decoder->rstate.value = NULL; nghttp3_rcbuf_decref(qnv.name); return rv; @@ -3250,7 +3258,9 @@ int nghttp3_qpack_decoder_dtable_literal_add(nghttp3_qpack_decoder *decoder) { rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0); nghttp3_rcbuf_decref(qnv.value); + decoder->rstate.value = NULL; nghttp3_rcbuf_decref(qnv.name); + decoder->rstate.name = NULL; return rv; } @@ -3818,6 +3828,9 @@ int nghttp3_qpack_decoder_cancel_stream(nghttp3_qpack_decoder *decoder, uint8_t *p; int rv; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + if (qpack_decoder_dbuf_overflow(decoder)) { return NGHTTP3_ERR_QPACK_FATAL; } @@ -4062,7 +4075,6 @@ void nghttp3_qpack_decoder_emit_literal(nghttp3_qpack_decoder *decoder, int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder, size_t hard_max_dtable_capacity, const nghttp3_mem *mem) { - int rv; nghttp3_qpack_encoder *p; p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_encoder)); @@ -4070,10 +4082,7 @@ int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder, return NGHTTP3_ERR_NOMEM; } - rv = nghttp3_qpack_encoder_init(p, hard_max_dtable_capacity, mem); - if (rv != 0) { - return rv; - } + nghttp3_qpack_encoder_init(p, hard_max_dtable_capacity, mem); *pencoder = p; @@ -4098,6 +4107,9 @@ int nghttp3_qpack_stream_context_new(nghttp3_qpack_stream_context **psctx, const nghttp3_mem *mem) { nghttp3_qpack_stream_context *p; + assert(stream_id >= 0); + assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT); + p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_stream_context)); if (p == NULL) { return NGHTTP3_ERR_NOMEM; @@ -4127,7 +4139,6 @@ int nghttp3_qpack_decoder_new(nghttp3_qpack_decoder **pdecoder, size_t hard_max_dtable_capacity, size_t max_blocked_streams, const nghttp3_mem *mem) { - int rv; nghttp3_qpack_decoder *p; p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_decoder)); @@ -4135,11 +4146,8 @@ int nghttp3_qpack_decoder_new(nghttp3_qpack_decoder **pdecoder, return NGHTTP3_ERR_NOMEM; } - rv = nghttp3_qpack_decoder_init(p, hard_max_dtable_capacity, - max_blocked_streams, mem); - if (rv != 0) { - return rv; - } + nghttp3_qpack_decoder_init(p, hard_max_dtable_capacity, max_blocked_streams, + mem); *pdecoder = p; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h index d2bb8a35811..cb82333abc4 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h @@ -270,16 +270,10 @@ struct nghttp3_qpack_encoder { * nghttp3_qpack_encoder_init initializes |encoder|. * |hard_max_dtable_capacity| is the upper bound of the dynamic table * capacity. |mem| is a memory allocator. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP3_ERR_NOMEM - * Out of memory. */ -int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder, - size_t hard_max_dtable_capacity, - const nghttp3_mem *mem); +void nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder, + size_t hard_max_dtable_capacity, + const nghttp3_mem *mem); /* * nghttp3_qpack_encoder_free frees memory allocated for |encoder|. @@ -800,17 +794,11 @@ struct nghttp3_qpack_decoder { * |hard_max_dtable_capacity| is the upper bound of the dynamic table * capacity. |max_blocked_streams| is the maximum number of stream * which can be blocked. |mem| is a memory allocator. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP3_ERR_NOMEM - * Out of memory. */ -int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder, - size_t hard_max_dtable_capacity, - size_t max_blocked_streams, - const nghttp3_mem *mem); +void nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder, + size_t hard_max_dtable_capacity, + size_t max_blocked_streams, + const nghttp3_mem *mem); /* * nghttp3_qpack_decoder_free frees memory allocated for |decoder|. diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack_huffman.c b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack_huffman.c index 3398f3f5080..dbc9a764e7b 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack_huffman.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack_huffman.c @@ -88,7 +88,9 @@ nghttp3_qpack_huffman_decode(nghttp3_qpack_huffman_decode_context *ctx, int fin) { uint8_t *p = dest; const uint8_t *end = src + srclen; - nghttp3_qpack_huffman_decode_node node = {ctx->fstate, 0}; + nghttp3_qpack_huffman_decode_node node = { + .fstate = ctx->fstate, + }; const nghttp3_qpack_huffman_decode_node *t = &node; uint8_t c; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_range.c b/deps/ngtcp2/nghttp3/lib/nghttp3_range.c index af810a2c592..b5f95bb83fc 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_range.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_range.c @@ -33,7 +33,7 @@ void nghttp3_range_init(nghttp3_range *r, uint64_t begin, uint64_t end) { nghttp3_range nghttp3_range_intersect(const nghttp3_range *a, const nghttp3_range *b) { - nghttp3_range r = {0, 0}; + nghttp3_range r = {0}; uint64_t begin = nghttp3_max_uint64(a->begin, b->begin); uint64_t end = nghttp3_min_uint64(a->end, b->end); diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c b/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c index 7d3ab39bf82..ccd1d3e99ab 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c @@ -33,18 +33,21 @@ #include "nghttp3_macro.h" +#ifndef NDEBUG static int ispow2(size_t n) { -#if defined(_MSC_VER) && !defined(__clang__) && \ - (defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941)) +# if defined(DISABLE_POPCNT) || \ + (defined(_MSC_VER) && !defined(__clang__) && \ + (defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))) return n && !(n & (n - 1)); -#elif defined(WIN32) +# elif defined(WIN32) return 1 == __popcnt((unsigned int)n); -#else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \ - (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */ +# else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \ + (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */ return 1 == __builtin_popcount((unsigned int)n); -#endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \ - (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */ +# endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \ + (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */ } +#endif /* !defined(NDEBUG) */ int nghttp3_ringbuf_init(nghttp3_ringbuf *rb, size_t nmemb, size_t size, const nghttp3_mem *mem) { diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c index 328cddd488f..9ae9d4850d0 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c @@ -44,7 +44,7 @@ /* NGHTTP3_MIN_RBLEN is the minimum length of nghttp3_ringbuf */ #define NGHTTP3_MIN_RBLEN 4 -nghttp3_objalloc_def(stream, nghttp3_stream, oplent); +nghttp3_objalloc_def(stream, nghttp3_stream, oplent) int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id, const nghttp3_stream_callbacks *callbacks, @@ -181,42 +181,45 @@ void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate) { nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint, const uint8_t *begin, const uint8_t *end, int fin) { - const uint8_t *orig_begin = begin; - size_t len; + size_t len, vlen; + uint8_t *p; assert(begin != end); if (rvint->left == 0) { assert(rvint->acc == 0); - len = nghttp3_get_varintlen(begin); - if (len <= (size_t)(end - begin)) { + vlen = nghttp3_get_varintlen(begin); + len = nghttp3_min_size(vlen, (size_t)(end - begin)); + if (vlen <= len) { nghttp3_get_varint(&rvint->acc, begin); - return (nghttp3_ssize)len; + return (nghttp3_ssize)vlen; } if (fin) { return NGHTTP3_ERR_INVALID_ARGUMENT; } - rvint->acc = nghttp3_get_varint_fb(begin++); - rvint->left = len - 1; + p = (uint8_t *)&rvint->acc + (sizeof(rvint->acc) - vlen); + memcpy(p, begin, len); + *p &= 0x3f; + rvint->left = vlen - len; + + return (nghttp3_ssize)len; } len = nghttp3_min_size(rvint->left, (size_t)(end - begin)); - end = begin + len; - - for (; begin != end;) { - rvint->acc = (rvint->acc << 8) + *begin++; - } - + p = (uint8_t *)&rvint->acc + (sizeof(rvint->acc) - rvint->left); + memcpy(p, begin, len); rvint->left -= len; - if (fin && rvint->left) { + if (rvint->left == 0) { + rvint->acc = (int64_t)nghttp3_ntohl64((uint64_t)rvint->acc); + } else if (fin) { return NGHTTP3_ERR_INVALID_ARGUMENT; } - return (nghttp3_ssize)(begin - orig_begin); + return (nghttp3_ssize)len; } int nghttp3_stream_frq_add(nghttp3_stream *stream, @@ -301,12 +304,6 @@ int nghttp3_stream_fill_outq(nghttp3_stream *stream) { return 0; } -static void typed_buf_shared_init(nghttp3_typed_buf *tbuf, - const nghttp3_buf *chunk) { - nghttp3_typed_buf_init(tbuf, chunk, NGHTTP3_BUF_TYPE_SHARED); - tbuf->buf.pos = tbuf->buf.last; -} - int nghttp3_stream_write_stream_type(nghttp3_stream *stream) { size_t len = nghttp3_put_varintlen((int64_t)stream->type); nghttp3_buf *chunk; @@ -319,7 +316,7 @@ int nghttp3_stream_write_stream_type(nghttp3_stream *stream) { } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_put_varint(chunk->last, (int64_t)stream->type); tbuf.buf.last = chunk->last; @@ -336,12 +333,19 @@ int nghttp3_stream_write_settings(nghttp3_stream *stream, struct { nghttp3_frame_settings settings; nghttp3_settings_entry iv[15]; - } fr; + } fr = { + .settings = + { + .hd = + { + .type = NGHTTP3_FRAME_SETTINGS, + }, + .niv = 3, + }, + }; nghttp3_settings_entry *iv; nghttp3_settings *local_settings = frent->aux.settings.local_settings; - fr.settings.hd.type = NGHTTP3_FRAME_SETTINGS; - fr.settings.niv = 3; iv = &fr.settings.iv[0]; iv[0].id = NGHTTP3_SETTINGS_ID_MAX_FIELD_SECTION_SIZE; @@ -373,7 +377,7 @@ int nghttp3_stream_write_settings(nghttp3_stream *stream, } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_frame_write_settings(chunk->last, &fr.settings); @@ -398,7 +402,7 @@ int nghttp3_stream_write_goaway(nghttp3_stream *stream, } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_frame_write_goaway(chunk->last, fr); @@ -423,7 +427,7 @@ int nghttp3_stream_write_priority_update(nghttp3_stream *stream, } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_frame_write_priority_update(chunk->last, fr); @@ -464,7 +468,7 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream, rv = nghttp3_qpack_encoder_encode(qenc, &pbuf, rbuf, ebuf, stream->node.id, nva, nvlen); if (rv != 0) { - goto fail; + return rv; } pbuflen = nghttp3_buf_len(&pbuf); @@ -482,11 +486,11 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream, rv = nghttp3_stream_ensure_chunk(stream, len); if (rv != 0) { - goto fail; + return rv; } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_frame_write_hd(chunk->last, &hd); @@ -498,13 +502,13 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream, rv = nghttp3_stream_outq_add(stream, &tbuf); if (rv != 0) { - goto fail; + return rv; } nghttp3_typed_buf_init(&tbuf, rbuf, NGHTTP3_BUF_TYPE_PRIVATE); rv = nghttp3_stream_outq_add(stream, &tbuf); if (rv != 0) { - goto fail; + return rv; } nghttp3_buf_init(rbuf); } else if (rbuflen) { @@ -513,7 +517,7 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream, rv = nghttp3_stream_outq_add(stream, &tbuf); if (rv != 0) { - goto fail; + return rv; } nghttp3_buf_reset(rbuf); } @@ -532,18 +536,18 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream, rv = nghttp3_stream_ensure_chunk(qenc_stream, ebuflen); if (rv != 0) { - goto fail; + return rv; } chunk = nghttp3_stream_get_chunk(qenc_stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_cpymem(chunk->last, ebuf->pos, ebuflen); tbuf.buf.last = chunk->last; rv = nghttp3_stream_outq_add(qenc_stream, &tbuf); if (rv != 0) { - goto fail; + return rv; } nghttp3_buf_reset(ebuf); } @@ -553,10 +557,6 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream, assert(0 == nghttp3_buf_len(ebuf)); return 0; - -fail: - - return rv; } int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof, @@ -635,7 +635,7 @@ int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof, } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); chunk->last = nghttp3_frame_write_hd(chunk->last, &hd); @@ -690,7 +690,7 @@ int nghttp3_stream_write_qpack_decoder_stream(nghttp3_stream *stream) { } chunk = nghttp3_stream_get_chunk(stream); - typed_buf_shared_init(&tbuf, chunk); + nghttp3_typed_buf_shared_init(&tbuf, chunk); nghttp3_qpack_decoder_write_decoder(qdec, chunk); @@ -717,17 +717,16 @@ int nghttp3_stream_outq_add(nghttp3_stream *stream, if (len) { dest = nghttp3_ringbuf_get(outq, len - 1); if (dest->type == tbuf->type && dest->type == NGHTTP3_BUF_TYPE_SHARED && - dest->buf.begin == tbuf->buf.begin && dest->buf.last == tbuf->buf.pos) { + dest->buf.end == tbuf->buf.end && dest->buf.last == tbuf->buf.pos) { /* If we have already written last entry, adjust outq_idx and offset so that this entry is eligible to send. */ if (len == stream->outq_idx) { --stream->outq_idx; - stream->outq_offset = nghttp3_buf_len(&dest->buf); } dest->buf.last = tbuf->buf.last; - /* TODO Is this required? */ - dest->buf.end = tbuf->buf.end; + + assert(dest->buf.end == tbuf->buf.end); return 0; } @@ -817,34 +816,24 @@ size_t nghttp3_stream_writev(nghttp3_stream *stream, int *pfin, nghttp3_ringbuf *outq = &stream->outq; size_t len = nghttp3_ringbuf_len(outq); size_t i = stream->outq_idx; - uint64_t offset = stream->outq_offset; size_t buflen; nghttp3_vec *vbegin = vec, *vend = vec + veccnt; nghttp3_typed_buf *tbuf; assert(veccnt > 0); - if (i < len) { + for (; i < len && vec != vend; ++i) { tbuf = nghttp3_ringbuf_get(outq, i); buflen = nghttp3_buf_len(&tbuf->buf); - if (offset < buflen) { - vec->base = tbuf->buf.pos + offset; - vec->len = (size_t)(buflen - offset); - ++vec; - } else { - /* This is the only case that satisfies offset >= buflen */ - assert(0 == offset); - assert(0 == buflen); + if (buflen == 0) { + continue; } - ++i; + vec->base = tbuf->buf.pos; + vec->len = buflen; - for (; i < len && vec != vend; ++i, ++vec) { - tbuf = nghttp3_ringbuf_get(outq, i); - vec->base = tbuf->buf.pos; - vec->len = nghttp3_buf_len(&tbuf->buf); - } + ++vec; } /* TODO Rework this if we have finished implementing HTTP @@ -859,26 +848,27 @@ void nghttp3_stream_add_outq_offset(nghttp3_stream *stream, size_t n) { nghttp3_ringbuf *outq = &stream->outq; size_t i; size_t len = nghttp3_ringbuf_len(outq); - uint64_t offset = stream->outq_offset + n; size_t buflen; nghttp3_typed_buf *tbuf; + stream->unsent_bytes -= n; + for (i = stream->outq_idx; i < len; ++i) { tbuf = nghttp3_ringbuf_get(outq, i); buflen = nghttp3_buf_len(&tbuf->buf); - if (offset >= buflen) { - offset -= buflen; - continue; + if (n < buflen) { + tbuf->buf.pos += n; + + break; } - break; + tbuf->buf.pos = tbuf->buf.last; + n -= buflen; } - assert(i < len || offset == 0); + assert(i < len || n == 0); - stream->unsent_bytes -= n; stream->outq_idx = i; - stream->outq_offset = offset; } int nghttp3_stream_outq_write_done(nghttp3_stream *stream) { @@ -904,7 +894,6 @@ static void stream_pop_outq_entry(nghttp3_stream *stream, chunk = nghttp3_ringbuf_get(chunks, 0); - assert(chunk->begin == tbuf->buf.begin); assert(chunk->end == tbuf->buf.end); if (chunk->last == tbuf->buf.last) { @@ -927,14 +916,13 @@ static void stream_pop_outq_entry(nghttp3_stream *stream, int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) { nghttp3_ringbuf *outq = &stream->outq; size_t buflen; - size_t npopped = 0; uint64_t nack; nghttp3_typed_buf *tbuf; int rv; for (; nghttp3_ringbuf_len(outq);) { tbuf = nghttp3_ringbuf_get(outq, 0); - buflen = nghttp3_buf_len(&tbuf->buf); + buflen = (size_t)(tbuf->buf.last - tbuf->buf.begin); /* For NGHTTP3_BUF_TYPE_ALIEN, we never add 0 length buffer. */ if (tbuf->type == NGHTTP3_BUF_TYPE_ALIEN && stream->ack_offset < offset && @@ -949,17 +937,13 @@ int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) { } } - if (offset >= stream->ack_base + buflen) { + if (stream->outq_idx > 0 && offset >= stream->ack_base + buflen) { stream_pop_outq_entry(stream, tbuf); stream->ack_base += buflen; stream->ack_offset = stream->ack_base; - ++npopped; - if (stream->outq_idx + 1 == npopped) { - stream->outq_offset = 0; - break; - } + --stream->outq_idx; continue; } @@ -967,13 +951,6 @@ int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) { break; } - assert(stream->outq_idx + 1 >= npopped); - if (stream->outq_idx >= npopped) { - stream->outq_idx -= npopped; - } else { - stream->outq_idx = 0; - } - stream->ack_offset = offset; return 0; @@ -1045,19 +1022,17 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, switch (stream->rx.hstate) { case NGHTTP3_HTTP_STATE_NONE: - return NGHTTP3_ERR_H3_INTERNAL_ERROR; + nghttp3_unreachable(); case NGHTTP3_HTTP_STATE_REQ_INITIAL: - switch (event) { - case NGHTTP3_HTTP_EVENT_HEADERS_BEGIN: - stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN; - return 0; - default: + if (event != NGHTTP3_HTTP_EVENT_HEADERS_BEGIN) { return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; } + + stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN; + + return 0; case NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN: - if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; - } + assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event); stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_HEADERS_END; return 0; case NGHTTP3_HTTP_STATE_REQ_HEADERS_END: @@ -1080,12 +1055,10 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_END; return 0; default: - return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; + nghttp3_unreachable(); } case NGHTTP3_HTTP_STATE_REQ_DATA_BEGIN: - if (event != NGHTTP3_HTTP_EVENT_DATA_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; - } + assert(NGHTTP3_HTTP_EVENT_DATA_END == event); stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_DATA_END; return 0; case NGHTTP3_HTTP_STATE_REQ_DATA_END: @@ -1108,12 +1081,10 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_END; return 0; default: - return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; + nghttp3_unreachable(); } case NGHTTP3_HTTP_STATE_REQ_TRAILERS_BEGIN: - if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; - } + assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event); stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_TRAILERS_END; return 0; case NGHTTP3_HTTP_STATE_REQ_TRAILERS_END: @@ -1129,7 +1100,7 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_END; return 0; case NGHTTP3_HTTP_STATE_REQ_END: - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; + return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; case NGHTTP3_HTTP_STATE_RESP_INITIAL: if (event != NGHTTP3_HTTP_EVENT_HEADERS_BEGIN) { return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; @@ -1137,9 +1108,7 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_HEADERS_BEGIN; return 0; case NGHTTP3_HTTP_STATE_RESP_HEADERS_BEGIN: - if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; - } + assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event); stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_HEADERS_END; return 0; case NGHTTP3_HTTP_STATE_RESP_HEADERS_END: @@ -1169,12 +1138,10 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_END; return 0; default: - return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; + nghttp3_unreachable(); } case NGHTTP3_HTTP_STATE_RESP_DATA_BEGIN: - if (event != NGHTTP3_HTTP_EVENT_DATA_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; - } + assert(NGHTTP3_HTTP_EVENT_DATA_END == event); stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_DATA_END; return 0; case NGHTTP3_HTTP_STATE_RESP_DATA_END: @@ -1197,17 +1164,15 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_END; return 0; default: - return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; + nghttp3_unreachable(); } case NGHTTP3_HTTP_STATE_RESP_TRAILERS_BEGIN: - if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; - } + assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event); stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_TRAILERS_END; return 0; case NGHTTP3_HTTP_STATE_RESP_TRAILERS_END: if (event != NGHTTP3_HTTP_EVENT_MSG_END) { - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; + return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; } rv = nghttp3_http_on_remote_end_stream(stream); if (rv != 0) { @@ -1216,7 +1181,7 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream, stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_END; return 0; case NGHTTP3_HTTP_STATE_RESP_END: - return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING; + return NGHTTP3_ERR_H3_FRAME_UNEXPECTED; default: nghttp3_unreachable(); } diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h index 7d296febf91..d24cae04470 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h @@ -223,9 +223,6 @@ struct nghttp3_stream { uint64_t unsent_bytes; /* outq_idx is an index into outq where next write is made. */ size_t outq_idx; - /* outq_offset is write offset relative to the element at outq_idx - in outq. */ - uint64_t outq_offset; /* ack_base is the number of bytes acknowledged by a remote endpoint where the first element in outq is positioned at. */ uint64_t ack_base; @@ -255,7 +252,7 @@ struct nghttp3_stream { }; }; -nghttp3_objalloc_decl(stream, nghttp3_stream, oplent); +nghttp3_objalloc_decl(stream, nghttp3_stream, oplent) typedef struct nghttp3_frame_entry { nghttp3_frame fr; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_version.c b/deps/ngtcp2/nghttp3/lib/nghttp3_version.c index 939821d84ea..b88e2255b25 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_version.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_version.c @@ -28,8 +28,11 @@ #include -static nghttp3_info version = {NGHTTP3_VERSION_AGE, NGHTTP3_VERSION_NUM, - NGHTTP3_VERSION}; +static nghttp3_info version = { + .age = NGHTTP3_VERSION_AGE, + .version_num = NGHTTP3_VERSION_NUM, + .version_str = NGHTTP3_VERSION, +}; const nghttp3_info *nghttp3_version(int least_version) { if (least_version > NGHTTP3_VERSION_NUM) { diff --git a/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.c b/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.c index d0328cf40c2..cee089d3944 100644 --- a/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.c +++ b/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.c @@ -30,38 +30,46 @@ #include #include -#define SF_STATE_DICT 0x08u -#define SF_STATE_LIST 0x10u -#define SF_STATE_ITEM 0x18u +#ifdef __AVX2__ +# include +#endif /* __AVX2__ */ -#define SF_STATE_INNER_LIST 0x04u +#define SFPARSE_STATE_DICT 0x08u +#define SFPARSE_STATE_LIST 0x10u +#define SFPARSE_STATE_ITEM 0x18u -#define SF_STATE_BEFORE 0x00u -#define SF_STATE_BEFORE_PARAMS 0x01u -#define SF_STATE_PARAMS 0x02u -#define SF_STATE_AFTER 0x03u +#define SFPARSE_STATE_INNER_LIST 0x04u -#define SF_STATE_OP_MASK 0x03u +#define SFPARSE_STATE_BEFORE 0x00u +#define SFPARSE_STATE_BEFORE_PARAMS 0x01u +#define SFPARSE_STATE_PARAMS 0x02u +#define SFPARSE_STATE_AFTER 0x03u -#define SF_SET_STATE_AFTER(NAME) (SF_STATE_##NAME | SF_STATE_AFTER) -#define SF_SET_STATE_BEFORE_PARAMS(NAME) \ - (SF_STATE_##NAME | SF_STATE_BEFORE_PARAMS) -#define SF_SET_STATE_INNER_LIST_BEFORE(NAME) \ - (SF_STATE_##NAME | SF_STATE_INNER_LIST | SF_STATE_BEFORE) +#define SFPARSE_STATE_OP_MASK 0x03u -#define SF_STATE_DICT_AFTER SF_SET_STATE_AFTER(DICT) -#define SF_STATE_DICT_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(DICT) -#define SF_STATE_DICT_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(DICT) +#define SFPARSE_SET_STATE_AFTER(NAME) \ + (SFPARSE_STATE_##NAME | SFPARSE_STATE_AFTER) +#define SFPARSE_SET_STATE_BEFORE_PARAMS(NAME) \ + (SFPARSE_STATE_##NAME | SFPARSE_STATE_BEFORE_PARAMS) +#define SFPARSE_SET_STATE_INNER_LIST_BEFORE(NAME) \ + (SFPARSE_STATE_##NAME | SFPARSE_STATE_INNER_LIST | SFPARSE_STATE_BEFORE) -#define SF_STATE_LIST_AFTER SF_SET_STATE_AFTER(LIST) -#define SF_STATE_LIST_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(LIST) -#define SF_STATE_LIST_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(LIST) +#define SFPARSE_STATE_DICT_AFTER SFPARSE_SET_STATE_AFTER(DICT) +#define SFPARSE_STATE_DICT_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(DICT) +#define SFPARSE_STATE_DICT_INNER_LIST_BEFORE \ + SFPARSE_SET_STATE_INNER_LIST_BEFORE(DICT) -#define SF_STATE_ITEM_AFTER SF_SET_STATE_AFTER(ITEM) -#define SF_STATE_ITEM_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(ITEM) -#define SF_STATE_ITEM_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(ITEM) +#define SFPARSE_STATE_LIST_AFTER SFPARSE_SET_STATE_AFTER(LIST) +#define SFPARSE_STATE_LIST_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(LIST) +#define SFPARSE_STATE_LIST_INNER_LIST_BEFORE \ + SFPARSE_SET_STATE_INNER_LIST_BEFORE(LIST) -#define SF_STATE_INITIAL 0x00u +#define SFPARSE_STATE_ITEM_AFTER SFPARSE_SET_STATE_AFTER(ITEM) +#define SFPARSE_STATE_ITEM_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(ITEM) +#define SFPARSE_STATE_ITEM_INNER_LIST_BEFORE \ + SFPARSE_SET_STATE_INNER_LIST_BEFORE(ITEM) + +#define SFPARSE_STATE_INITIAL 0x00u #define DIGIT_CASES \ case '0': \ @@ -380,40 +388,108 @@ static int is_ws(uint8_t c) { } } -static int parser_eof(sf_parser *sfp) { return sfp->pos == sfp->end; } +#ifdef __AVX2__ +# ifdef _MSC_VER +# include -static void parser_discard_ows(sf_parser *sfp) { +static int ctz(unsigned int v) { + unsigned long n; + + /* Assume that v is not 0. */ + _BitScanForward(&n, v); + + return (int)n; +} +# else /* !_MSC_VER */ +# define ctz __builtin_ctz +# endif /* !_MSC_VER */ +#endif /* __AVX2__ */ + +static int parser_eof(sfparse_parser *sfp) { return sfp->pos == sfp->end; } + +static void parser_discard_ows(sfparse_parser *sfp) { for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos) ; } -static void parser_discard_sp(sf_parser *sfp) { +static void parser_discard_sp(sfparse_parser *sfp) { for (; !parser_eof(sfp) && *sfp->pos == ' '; ++sfp->pos) ; } -static void parser_set_op_state(sf_parser *sfp, uint32_t op) { - sfp->state &= ~SF_STATE_OP_MASK; +static void parser_set_op_state(sfparse_parser *sfp, uint32_t op) { + sfp->state &= ~SFPARSE_STATE_OP_MASK; sfp->state |= op; } -static void parser_unset_inner_list_state(sf_parser *sfp) { - sfp->state &= ~SF_STATE_INNER_LIST; +static void parser_unset_inner_list_state(sfparse_parser *sfp) { + sfp->state &= ~SFPARSE_STATE_INNER_LIST; } -static int parser_key(sf_parser *sfp, sf_vec *dest) { +#ifdef __AVX2__ +static const uint8_t *find_char_key(const uint8_t *first, const uint8_t *last) { + const __m256i us = _mm256_set1_epi8('_'); + const __m256i ds = _mm256_set1_epi8('-'); + const __m256i dot = _mm256_set1_epi8('.'); + const __m256i ast = _mm256_set1_epi8('*'); + const __m256i r0l = _mm256_set1_epi8('0' - 1); + const __m256i r0r = _mm256_set1_epi8('9' + 1); + const __m256i r1l = _mm256_set1_epi8('a' - 1); + const __m256i r1r = _mm256_set1_epi8('z' + 1); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_cmpeq_epi8(s, us); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ds), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dot), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ast), x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)), + x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), + x); + + m = ~(uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_key(sfparse_parser *sfp, sfparse_vec *dest) { const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ switch (*sfp->pos) { case '*': LCALPHA_CASES: break; default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } base = sfp->pos++; +#ifdef __AVX2__ + if (sfp->end - sfp->pos >= 32) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + + sfp->pos = find_char_key(sfp->pos, last); + if (sfp->pos != last) { + goto fin; + } + } +#endif /* __AVX2__ */ + for (; !parser_eof(sfp); ++sfp->pos) { switch (*sfp->pos) { case '_': @@ -428,6 +504,9 @@ static int parser_key(sf_parser *sfp, sf_vec *dest) { break; } +#ifdef __AVX2__ +fin: +#endif /* __AVX2__ */ if (dest) { dest->base = (uint8_t *)base; dest->len = (size_t)(sfp->pos - dest->base); @@ -436,7 +515,7 @@ static int parser_key(sf_parser *sfp, sf_vec *dest) { return 0; } -static int parser_number(sf_parser *sfp, sf_value *dest) { +static int parser_number(sfparse_parser *sfp, sfparse_value *dest) { int sign = 1; int64_t value = 0; size_t len = 0; @@ -445,7 +524,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { if (*sfp->pos == '-') { ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } sign = -1; @@ -457,7 +536,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { switch (*sfp->pos) { DIGIT_CASES: if (++len > 15) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } value *= 10; @@ -470,13 +549,13 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { } if (len == 0) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } if (parser_eof(sfp) || *sfp->pos != '.') { if (dest) { - dest->type = SF_TYPE_INTEGER; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_INTEGER; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->integer = value * sign; } @@ -486,7 +565,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { /* decimal */ if (len > 12) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } fpos = len; @@ -497,7 +576,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { switch (*sfp->pos) { DIGIT_CASES: if (++len > 15) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } value *= 10; @@ -510,12 +589,12 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { } if (fpos == len || len - fpos > 3) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } if (dest) { - dest->type = SF_TYPE_DECIMAL; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_DECIMAL; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->decimal.numer = value * sign; switch (len - fpos) { @@ -537,9 +616,9 @@ static int parser_number(sf_parser *sfp, sf_value *dest) { return 0; } -static int parser_date(sf_parser *sfp, sf_value *dest) { +static int parser_date(sfparse_parser *sfp, sfparse_value *dest) { int rv; - sf_value val; + sfparse_value val; /* The first byte has already been validated by the caller. */ assert('@' == *sfp->pos); @@ -547,7 +626,7 @@ static int parser_date(sf_parser *sfp, sf_value *dest) { ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } rv = parser_number(sfp, &val); @@ -555,27 +634,93 @@ static int parser_date(sf_parser *sfp, sf_value *dest) { return rv; } - if (val.type != SF_TYPE_INTEGER) { - return SF_ERR_PARSE_ERROR; + if (val.type != SFPARSE_TYPE_INTEGER) { + return SFPARSE_ERR_PARSE; } if (dest) { *dest = val; - dest->type = SF_TYPE_DATE; + dest->type = SFPARSE_TYPE_DATE; } return 0; } -static int parser_string(sf_parser *sfp, sf_value *dest) { +#ifdef __AVX2__ +static const uint8_t *find_char_string(const uint8_t *first, + const uint8_t *last) { + const __m256i bs = _mm256_set1_epi8('\\'); + const __m256i dq = _mm256_set1_epi8('"'); + const __m256i del = _mm256_set1_epi8(0x7f); + const __m256i sp = _mm256_set1_epi8(' '); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_cmpgt_epi8(sp, s); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, bs), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dq), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, del), x); + + m = (uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_string(sfparse_parser *sfp, sfparse_value *dest) { const uint8_t *base; - uint32_t flags = SF_VALUE_FLAG_NONE; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ + uint32_t flags = SFPARSE_VALUE_FLAG_NONE; /* The first byte has already been validated by the caller. */ assert('"' == *sfp->pos); base = ++sfp->pos; +#ifdef __AVX2__ + for (; sfp->end - sfp->pos >= 32; ++sfp->pos) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + + sfp->pos = find_char_string(sfp->pos, last); + if (sfp->pos == last) { + break; + } + + switch (*sfp->pos) { + case '\\': + ++sfp->pos; + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + switch (*sfp->pos) { + case '"': + case '\\': + flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING; + + break; + default: + return SFPARSE_ERR_PARSE; + } + + break; + case '"': + goto fin; + default: + return SFPARSE_ERR_PARSE; + } + } +#endif /* __AVX2__ */ + for (; !parser_eof(sfp); ++sfp->pos) { switch (*sfp->pos) { X20_21_CASES: @@ -585,45 +730,116 @@ static int parser_string(sf_parser *sfp, sf_value *dest) { case '\\': ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } switch (*sfp->pos) { case '"': case '\\': - flags = SF_VALUE_FLAG_ESCAPED_STRING; + flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING; break; default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } break; case '"': - if (dest) { - dest->type = SF_TYPE_STRING; - dest->flags = flags; - dest->vec.len = (size_t)(sfp->pos - base); - dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; - } - - ++sfp->pos; - - return 0; + goto fin; default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } } - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; + +fin: + if (dest) { + dest->type = SFPARSE_TYPE_STRING; + dest->flags = flags; + dest->vec.len = (size_t)(sfp->pos - base); + dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; + } + + ++sfp->pos; + + return 0; } -static int parser_token(sf_parser *sfp, sf_value *dest) { +#ifdef __AVX2__ +static const uint8_t *find_char_token(const uint8_t *first, + const uint8_t *last) { + /* r0: !..:, excluding "(), + r1: A..Z + r2: ^..~, excluding {} */ + const __m256i r0l = _mm256_set1_epi8('!' - 1); + const __m256i r0r = _mm256_set1_epi8(':' + 1); + const __m256i dq = _mm256_set1_epi8('"'); + const __m256i prl = _mm256_set1_epi8('('); + const __m256i prr = _mm256_set1_epi8(')'); + const __m256i comma = _mm256_set1_epi8(','); + const __m256i r1l = _mm256_set1_epi8('A' - 1); + const __m256i r1r = _mm256_set1_epi8('Z' + 1); + const __m256i r2l = _mm256_set1_epi8('^' - 1); + const __m256i r2r = _mm256_set1_epi8('~' + 1); + const __m256i cbl = _mm256_set1_epi8('{'); + const __m256i cbr = _mm256_set1_epi8('}'); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, comma), + _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, prr), + _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, prl), + _mm256_andnot_si256(_mm256_cmpeq_epi8(s, dq), + _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), + _mm256_cmpgt_epi8(r0r, s)))))); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), + x); + x = _mm256_or_si256( + _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, cbr), + _mm256_andnot_si256(_mm256_cmpeq_epi8(s, cbl), + _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), + _mm256_cmpgt_epi8(r2r, s)))), + x); + + m = ~(uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_token(sfparse_parser *sfp, sfparse_value *dest) { const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ /* The first byte has already been validated by the caller. */ base = sfp->pos++; +#ifdef __AVX2__ + if (sfp->end - sfp->pos >= 32) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + + sfp->pos = find_char_token(sfp->pos, last); + if (sfp->pos != last) { + goto fin; + } + } +#endif /* __AVX2__ */ + for (; !parser_eof(sfp); ++sfp->pos) { switch (*sfp->pos) { TOKEN_CASES: @@ -633,9 +849,12 @@ static int parser_token(sf_parser *sfp, sf_value *dest) { break; } +#ifdef __AVX2__ +fin: +#endif /* __AVX2__ */ if (dest) { - dest->type = SF_TYPE_TOKEN; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_TOKEN; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->vec.base = (uint8_t *)base; dest->vec.len = (size_t)(sfp->pos - base); } @@ -643,14 +862,63 @@ static int parser_token(sf_parser *sfp, sf_value *dest) { return 0; } -static int parser_byteseq(sf_parser *sfp, sf_value *dest) { +#ifdef __AVX2__ +static const uint8_t *find_char_byteseq(const uint8_t *first, + const uint8_t *last) { + const __m256i pls = _mm256_set1_epi8('+'); + const __m256i fs = _mm256_set1_epi8('/'); + const __m256i r0l = _mm256_set1_epi8('0' - 1); + const __m256i r0r = _mm256_set1_epi8('9' + 1); + const __m256i r1l = _mm256_set1_epi8('A' - 1); + const __m256i r1r = _mm256_set1_epi8('Z' + 1); + const __m256i r2l = _mm256_set1_epi8('a' - 1); + const __m256i r2r = _mm256_set1_epi8('z' + 1); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_cmpeq_epi8(s, pls); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, fs), x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)), + x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), + x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), _mm256_cmpgt_epi8(r2r, s)), + x); + + m = ~(uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_byteseq(sfparse_parser *sfp, sfparse_value *dest) { const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ /* The first byte has already been validated by the caller. */ assert(':' == *sfp->pos); base = ++sfp->pos; +#ifdef __AVX2__ + if (sfp->end - sfp->pos >= 32) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + sfp->pos = find_char_byteseq(sfp->pos, last); + } +#endif /* __AVX2__ */ + for (; !parser_eof(sfp); ++sfp->pos) { switch (*sfp->pos) { case '+': @@ -662,12 +930,12 @@ static int parser_byteseq(sf_parser *sfp, sf_value *dest) { switch ((sfp->pos - base) & 0x3) { case 0: case 1: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; case 2: ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } if (*sfp->pos == '=') { @@ -682,27 +950,27 @@ static int parser_byteseq(sf_parser *sfp, sf_value *dest) { } if (parser_eof(sfp) || *sfp->pos != ':') { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } goto fin; case ':': if (((sfp->pos - base) & 0x3) == 1) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } goto fin; default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } } - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; fin: if (dest) { - dest->type = SF_TYPE_BYTESEQ; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_BYTESEQ; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->vec.len = (size_t)(sfp->pos - base); dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; } @@ -712,7 +980,7 @@ fin: return 0; } -static int parser_boolean(sf_parser *sfp, sf_value *dest) { +static int parser_boolean(sfparse_parser *sfp, sfparse_value *dest) { int b; /* The first byte has already been validated by the caller. */ @@ -721,7 +989,7 @@ static int parser_boolean(sf_parser *sfp, sf_value *dest) { ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } switch (*sfp->pos) { @@ -734,14 +1002,14 @@ static int parser_boolean(sf_parser *sfp, sf_value *dest) { break; default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } ++sfp->pos; if (dest) { - dest->type = SF_TYPE_BOOLEAN; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_BOOLEAN; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->boolean = b; } @@ -847,7 +1115,7 @@ static void utf8_decode(uint32_t *state, uint8_t byte) { /* End of utf8 dfa */ -static int parser_dispstring(sf_parser *sfp, sf_value *dest) { +static int parser_dispstring(sfparse_parser *sfp, sfparse_value *dest) { const uint8_t *base; uint8_t c; uint32_t utf8state = UTF8_ACCEPT; @@ -857,7 +1125,7 @@ static int parser_dispstring(sf_parser *sfp, sf_value *dest) { ++sfp->pos; if (parser_eof(sfp) || *sfp->pos != '"') { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } base = ++sfp->pos; @@ -866,32 +1134,32 @@ static int parser_dispstring(sf_parser *sfp, sf_value *dest) { switch (*sfp->pos) { X00_1F_CASES: X7F_FF_CASES: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; case '%': ++sfp->pos; if (sfp->pos + 2 > sfp->end) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } if (pctdecode(&c, &sfp->pos) != 0) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } utf8_decode(&utf8state, c); if (utf8state == UTF8_REJECT) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } break; case '"': if (utf8state != UTF8_ACCEPT) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } if (dest) { - dest->type = SF_TYPE_DISPSTRING; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_DISPSTRING; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->vec.len = (size_t)(sfp->pos - base); dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; } @@ -901,17 +1169,17 @@ static int parser_dispstring(sf_parser *sfp, sf_value *dest) { return 0; default: if (utf8state != UTF8_ACCEPT) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } ++sfp->pos; } } - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } -static int parser_bare_item(sf_parser *sfp, sf_value *dest) { +static int parser_bare_item(sfparse_parser *sfp, sfparse_value *dest) { switch (*sfp->pos) { case '"': return parser_string(sfp, dest); @@ -930,28 +1198,29 @@ static int parser_bare_item(sf_parser *sfp, sf_value *dest) { case '%': return parser_dispstring(sfp, dest); default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } } -static int parser_skip_inner_list(sf_parser *sfp); +static int parser_skip_inner_list(sfparse_parser *sfp); -int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { +int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value) { int rv; - switch (sfp->state & SF_STATE_OP_MASK) { - case SF_STATE_BEFORE: + switch (sfp->state & SFPARSE_STATE_OP_MASK) { + case SFPARSE_STATE_BEFORE: rv = parser_skip_inner_list(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_BEFORE_PARAMS: - parser_set_op_state(sfp, SF_STATE_PARAMS); + case SFPARSE_STATE_BEFORE_PARAMS: + parser_set_op_state(sfp, SFPARSE_STATE_PARAMS); break; - case SF_STATE_PARAMS: + case SFPARSE_STATE_PARAMS: break; default: assert(0); @@ -959,16 +1228,16 @@ int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { } if (parser_eof(sfp) || *sfp->pos != ';') { - parser_set_op_state(sfp, SF_STATE_AFTER); + parser_set_op_state(sfp, SFPARSE_STATE_AFTER); - return SF_ERR_EOF; + return SFPARSE_ERR_EOF; } ++sfp->pos; parser_discard_sp(sfp); if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } rv = parser_key(sfp, dest_key); @@ -978,8 +1247,8 @@ int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { if (parser_eof(sfp) || *sfp->pos != '=') { if (dest_value) { - dest_value->type = SF_TYPE_BOOLEAN; - dest_value->flags = SF_VALUE_FLAG_NONE; + dest_value->type = SFPARSE_TYPE_BOOLEAN; + dest_value->flags = SFPARSE_VALUE_FLAG_NONE; dest_value->boolean = 1; } @@ -989,23 +1258,23 @@ int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } return parser_bare_item(sfp, dest_value); } -static int parser_skip_params(sf_parser *sfp) { +static int parser_skip_params(sfparse_parser *sfp) { int rv; for (;;) { - rv = sf_parser_param(sfp, NULL, NULL); + rv = sfparse_parser_param(sfp, NULL, NULL); switch (rv) { case 0: break; - case SF_ERR_EOF: + case SFPARSE_ERR_EOF: return 0; - case SF_ERR_PARSE_ERROR: + case SFPARSE_ERR_PARSE: return rv; default: assert(0); @@ -1014,45 +1283,45 @@ static int parser_skip_params(sf_parser *sfp) { } } -int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) { +int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest) { int rv; - switch (sfp->state & SF_STATE_OP_MASK) { - case SF_STATE_BEFORE: + switch (sfp->state & SFPARSE_STATE_OP_MASK) { + case SFPARSE_STATE_BEFORE: parser_discard_sp(sfp); if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } break; - case SF_STATE_BEFORE_PARAMS: + case SFPARSE_STATE_BEFORE_PARAMS: rv = parser_skip_params(sfp); if (rv != 0) { return rv; } - /* Technically, we are entering SF_STATE_AFTER, but we will set + /* Technically, we are entering SFPARSE_STATE_AFTER, but we will set another state without reading the state. */ - /* parser_set_op_state(sfp, SF_STATE_AFTER); */ + /* parser_set_op_state(sfp, SFPARSE_STATE_AFTER); */ /* fall through */ - case SF_STATE_AFTER: + case SFPARSE_STATE_AFTER: if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } switch (*sfp->pos) { case ' ': parser_discard_sp(sfp); if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } break; case ')': break; default: - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } break; @@ -1065,9 +1334,9 @@ int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) { ++sfp->pos; parser_unset_inner_list_state(sfp); - parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS); + parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS); - return SF_ERR_EOF; + return SFPARSE_ERR_EOF; } rv = parser_bare_item(sfp, dest); @@ -1075,22 +1344,22 @@ int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) { return rv; } - parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS); + parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS); return 0; } -static int parser_skip_inner_list(sf_parser *sfp) { +static int parser_skip_inner_list(sfparse_parser *sfp) { int rv; for (;;) { - rv = sf_parser_inner_list(sfp, NULL); + rv = sfparse_parser_inner_list(sfp, NULL); switch (rv) { case 0: break; - case SF_ERR_EOF: + case SFPARSE_ERR_EOF: return 0; - case SF_ERR_PARSE_ERROR: + case SFPARSE_ERR_PARSE: return rv; default: assert(0); @@ -1099,39 +1368,39 @@ static int parser_skip_inner_list(sf_parser *sfp) { } } -static int parser_next_key_or_item(sf_parser *sfp) { +static int parser_next_key_or_item(sfparse_parser *sfp) { parser_discard_ows(sfp); if (parser_eof(sfp)) { - return SF_ERR_EOF; + return SFPARSE_ERR_EOF; } if (*sfp->pos != ',') { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } ++sfp->pos; parser_discard_ows(sfp); if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } return 0; } -static int parser_dict_value(sf_parser *sfp, sf_value *dest) { +static int parser_dict_value(sfparse_parser *sfp, sfparse_value *dest) { int rv; if (parser_eof(sfp) || *(sfp->pos) != '=') { /* Boolean true */ if (dest) { - dest->type = SF_TYPE_BOOLEAN; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_BOOLEAN; + dest->flags = SFPARSE_VALUE_FLAG_NONE; dest->boolean = 1; } - sfp->state = SF_STATE_DICT_BEFORE_PARAMS; + sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS; return 0; } @@ -1139,18 +1408,18 @@ static int parser_dict_value(sf_parser *sfp, sf_value *dest) { ++sfp->pos; if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } if (*sfp->pos == '(') { if (dest) { - dest->type = SF_TYPE_INNER_LIST; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_INNER_LIST; + dest->flags = SFPARSE_VALUE_FLAG_NONE; } ++sfp->pos; - sfp->state = SF_STATE_DICT_INNER_LIST_BEFORE; + sfp->state = SFPARSE_STATE_DICT_INNER_LIST_BEFORE; return 0; } @@ -1160,41 +1429,42 @@ static int parser_dict_value(sf_parser *sfp, sf_value *dest) { return rv; } - sfp->state = SF_STATE_DICT_BEFORE_PARAMS; + sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS; return 0; } -int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { +int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value) { int rv; switch (sfp->state) { - case SF_STATE_DICT_INNER_LIST_BEFORE: + case SFPARSE_STATE_DICT_INNER_LIST_BEFORE: rv = parser_skip_inner_list(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_DICT_BEFORE_PARAMS: + case SFPARSE_STATE_DICT_BEFORE_PARAMS: rv = parser_skip_params(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_DICT_AFTER: + case SFPARSE_STATE_DICT_AFTER: rv = parser_next_key_or_item(sfp); if (rv != 0) { return rv; } break; - case SF_STATE_INITIAL: + case SFPARSE_STATE_INITIAL: parser_discard_sp(sfp); if (parser_eof(sfp)) { - return SF_ERR_EOF; + return SFPARSE_ERR_EOF; } break; @@ -1211,36 +1481,36 @@ int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { return parser_dict_value(sfp, dest_value); } -int sf_parser_list(sf_parser *sfp, sf_value *dest) { +int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest) { int rv; switch (sfp->state) { - case SF_STATE_LIST_INNER_LIST_BEFORE: + case SFPARSE_STATE_LIST_INNER_LIST_BEFORE: rv = parser_skip_inner_list(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_LIST_BEFORE_PARAMS: + case SFPARSE_STATE_LIST_BEFORE_PARAMS: rv = parser_skip_params(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_LIST_AFTER: + case SFPARSE_STATE_LIST_AFTER: rv = parser_next_key_or_item(sfp); if (rv != 0) { return rv; } break; - case SF_STATE_INITIAL: + case SFPARSE_STATE_INITIAL: parser_discard_sp(sfp); if (parser_eof(sfp)) { - return SF_ERR_EOF; + return SFPARSE_ERR_EOF; } break; @@ -1251,13 +1521,13 @@ int sf_parser_list(sf_parser *sfp, sf_value *dest) { if (*sfp->pos == '(') { if (dest) { - dest->type = SF_TYPE_INNER_LIST; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_INNER_LIST; + dest->flags = SFPARSE_VALUE_FLAG_NONE; } ++sfp->pos; - sfp->state = SF_STATE_LIST_INNER_LIST_BEFORE; + sfp->state = SFPARSE_STATE_LIST_INNER_LIST_BEFORE; return 0; } @@ -1267,45 +1537,45 @@ int sf_parser_list(sf_parser *sfp, sf_value *dest) { return rv; } - sfp->state = SF_STATE_LIST_BEFORE_PARAMS; + sfp->state = SFPARSE_STATE_LIST_BEFORE_PARAMS; return 0; } -int sf_parser_item(sf_parser *sfp, sf_value *dest) { +int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest) { int rv; switch (sfp->state) { - case SF_STATE_INITIAL: + case SFPARSE_STATE_INITIAL: parser_discard_sp(sfp); if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } break; - case SF_STATE_ITEM_INNER_LIST_BEFORE: + case SFPARSE_STATE_ITEM_INNER_LIST_BEFORE: rv = parser_skip_inner_list(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_ITEM_BEFORE_PARAMS: + case SFPARSE_STATE_ITEM_BEFORE_PARAMS: rv = parser_skip_params(sfp); if (rv != 0) { return rv; } /* fall through */ - case SF_STATE_ITEM_AFTER: + case SFPARSE_STATE_ITEM_AFTER: parser_discard_sp(sfp); if (!parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; + return SFPARSE_ERR_PARSE; } - return SF_ERR_EOF; + return SFPARSE_ERR_EOF; default: assert(0); abort(); @@ -1313,13 +1583,13 @@ int sf_parser_item(sf_parser *sfp, sf_value *dest) { if (*sfp->pos == '(') { if (dest) { - dest->type = SF_TYPE_INNER_LIST; - dest->flags = SF_VALUE_FLAG_NONE; + dest->type = SFPARSE_TYPE_INNER_LIST; + dest->flags = SFPARSE_VALUE_FLAG_NONE; } ++sfp->pos; - sfp->state = SF_STATE_ITEM_INNER_LIST_BEFORE; + sfp->state = SFPARSE_STATE_ITEM_INNER_LIST_BEFORE; return 0; } @@ -1329,12 +1599,13 @@ int sf_parser_item(sf_parser *sfp, sf_value *dest) { return rv; } - sfp->state = SF_STATE_ITEM_BEFORE_PARAMS; + sfp->state = SFPARSE_STATE_ITEM_BEFORE_PARAMS; return 0; } -void sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen) { +void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data, + size_t datalen) { if (datalen == 0) { sfp->pos = sfp->end = NULL; } else { @@ -1342,10 +1613,10 @@ void sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen) { sfp->end = data + datalen; } - sfp->state = SF_STATE_INITIAL; + sfp->state = SFPARSE_STATE_INITIAL; } -void sf_unescape(sf_vec *dest, const sf_vec *src) { +void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src) { const uint8_t *p, *q; uint8_t *o; size_t len, slen; @@ -1381,23 +1652,22 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) { } } -void sf_base64decode(sf_vec *dest, const sf_vec *src) { +void sfparse_base64decode(sfparse_vec *dest, const sfparse_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; @@ -1478,7 +1748,7 @@ fin: dest->len = (size_t)(o - dest->base); } -void sf_pctdecode(sf_vec *dest, const sf_vec *src) { +void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src) { const uint8_t *p, *q; uint8_t *o; size_t len, slen; diff --git a/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h b/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h index 01cc947d4d6..9341221a099 100644 --- a/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h +++ b/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h @@ -31,90 +31,90 @@ libcurl) */ #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) # define WIN32 -#endif +#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */ #ifdef __cplusplus extern "C" { -#endif +#endif /* defined(__cplusplus) */ #if defined(_MSC_VER) && (_MSC_VER < 1800) /* MSVC < 2013 does not have inttypes.h because it is not C99 compliant. See compiler macros and version number in https://sourceforge.net/p/predef/wiki/Compilers/ */ # include -#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ +#else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */ # include -#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ +#endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */ #include #include /** * @enum * - * :type:`sf_type` defines value type. + * :type:`sfparse_type` defines value type. */ -typedef enum sf_type { +typedef enum sfparse_type { /** - * :enum:`SF_TYPE_BOOLEAN` indicates boolean type. + * :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type. */ - SF_TYPE_BOOLEAN, + SFPARSE_TYPE_BOOLEAN, /** - * :enum:`SF_TYPE_INTEGER` indicates integer type. + * :enum:`SFPARSE_TYPE_INTEGER` indicates integer type. */ - SF_TYPE_INTEGER, + SFPARSE_TYPE_INTEGER, /** - * :enum:`SF_TYPE_DECIMAL` indicates decimal type. + * :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type. */ - SF_TYPE_DECIMAL, + SFPARSE_TYPE_DECIMAL, /** - * :enum:`SF_TYPE_STRING` indicates string type. + * :enum:`SFPARSE_TYPE_STRING` indicates string type. */ - SF_TYPE_STRING, + SFPARSE_TYPE_STRING, /** - * :enum:`SF_TYPE_TOKEN` indicates token type. + * :enum:`SFPARSE_TYPE_TOKEN` indicates token type. */ - SF_TYPE_TOKEN, + SFPARSE_TYPE_TOKEN, /** - * :enum:`SF_TYPE_BYTESEQ` indicates byte sequence type. + * :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type. */ - SF_TYPE_BYTESEQ, + SFPARSE_TYPE_BYTESEQ, /** - * :enum:`SF_TYPE_INNER_LIST` indicates inner list type. + * :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type. */ - SF_TYPE_INNER_LIST, + SFPARSE_TYPE_INNER_LIST, /** - * :enum:`SF_TYPE_DATE` indicates date type. + * :enum:`SFPARSE_TYPE_DATE` indicates date type. */ - SF_TYPE_DATE, + SFPARSE_TYPE_DATE, /** - * :enum:`SF_TYPE_DISPSTRING` indicates display string type. + * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type. */ - SF_TYPE_DISPSTRING -} sf_type; + SFPARSE_TYPE_DISPSTRING +} sfparse_type; /** * @macro * - * :macro:`SF_ERR_PARSE_ERROR` indicates fatal parse error has + * :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has * occurred, and it is not possible to continue the processing. */ -#define SF_ERR_PARSE_ERROR -1 +#define SFPARSE_ERR_PARSE -1 /** * @macro * - * :macro:`SF_ERR_EOF` indicates that there is nothing left to read. - * The context of this error varies depending on the function that - * returns this error code. + * :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to + * read. The context of this error varies depending on the function + * that returns this error code. */ -#define SF_ERR_EOF -2 +#define SFPARSE_ERR_EOF -2 /** * @struct * - * :type:`sf_vec` stores sequence of bytes. + * :type:`sfparse_vec` stores sequence of bytes. */ -typedef struct sf_vec { +typedef struct sfparse_vec { /** * :member:`base` points to the beginning of the sequence of bytes. */ @@ -123,29 +123,29 @@ typedef struct sf_vec { * :member:`len` is the number of bytes contained in this sequence. */ size_t len; -} sf_vec; +} sfparse_vec; /** * @macro * - * :macro:`SF_VALUE_FLAG_NONE` indicates no flag set. + * :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set. */ -#define SF_VALUE_FLAG_NONE 0x0u +#define SFPARSE_VALUE_FLAG_NONE 0x0u /** * @macro * - * :macro:`SF_VALUE_FLAG_ESCAPED_STRING` indicates that a string + * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string * contains escaped character(s). */ -#define SF_VALUE_FLAG_ESCAPED_STRING 0x1u +#define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u /** * @struct * - * :type:`sf_decimal` contains decimal value. + * :type:`sfparse_decimal` contains decimal value. */ -typedef struct sf_decimal { +typedef struct sfparse_decimal { /** * :member:`numer` contains numerator of the decimal value. */ @@ -154,275 +154,289 @@ typedef struct sf_decimal { * :member:`denom` contains denominator of the decimal value. */ int64_t denom; -} sf_decimal; +} sfparse_decimal; /** * @struct * - * :type:`sf_value` stores a Structured Field item. For Inner List, - * only type is set to :enum:`sf_type.SF_TYPE_INNER_LIST`. In order - * to read the items contained in an inner list, call - * `sf_parser_inner_list`. + * :type:`sfparse_value` stores a Structured Field item. For Inner + * List, only type is set to + * :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`. In order to read the + * items contained in an inner list, call `sfparse_parser_inner_list`. */ -typedef struct sf_value { +typedef struct sfparse_value { /** * :member:`type` is the type of the value contained in this * particular object. */ - sf_type type; + sfparse_type type; /** * :member:`flags` is bitwise OR of one or more of - * :macro:`SF_VALUE_FLAG_* `. + * :macro:`SFPARSE_VALUE_FLAG_* `. */ uint32_t flags; /** * @anonunion_start * - * @sf_value_value + * @sfparse_value_value */ union { /** * :member:`boolean` contains boolean value if :member:`type` == - * :enum:`sf_type.SF_TYPE_BOOLEAN`. 1 indicates true, and 0 - * indicates false. + * :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`. 1 indicates true, + * and 0 indicates false. */ int boolean; /** * :member:`integer` contains integer value if :member:`type` is - * either :enum:`sf_type.SF_TYPE_INTEGER` or - * :enum:`sf_type.SF_TYPE_DATE`. + * either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or + * :enum:`sfparse_type.SFPARSE_TYPE_DATE`. */ int64_t integer; /** * :member:`decimal` contains decimal value if :member:`type` == - * :enum:`sf_type.SF_TYPE_DECIMAL`. + * :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`. */ - sf_decimal decimal; + sfparse_decimal decimal; /** * :member:`vec` contains sequence of bytes if :member:`type` is - * either :enum:`sf_type.SF_TYPE_STRING`, - * :enum:`sf_type.SF_TYPE_TOKEN`, :enum:`sf_type.SF_TYPE_BYTESEQ`, - * or :enum:`sf_type.SF_TYPE_DISPSTRING`. + * either :enum:`sfparse_type.SFPARSE_TYPE_STRING`, + * :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`, + * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or + * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`. * - * For :enum:`sf_type.SF_TYPE_STRING`, this field contains one or - * more escaped characters if :member:`flags` has - * :macro:`SF_VALUE_FLAG_ESCAPED_STRING` set. To unescape the - * string, use `sf_unescape`. + * For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field + * contains one or more escaped characters if :member:`flags` has + * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set. To unescape + * the string, use `sfparse_unescape`. * - * For :enum:`sf_type.SF_TYPE_BYTESEQ`, this field contains base64 - * encoded string. To decode this byte string, use - * `sf_base64decode`. + * For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field + * contains base64 encoded string. To decode this byte string, + * use `sfparse_base64decode`. * - * For :enum:`sf_type.SF_TYPE_DISPSTRING`, this field may contain - * percent-encoded UTF-8 byte sequences. To decode it, use - * `sf_pctdecode`. + * For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field + * may contain percent-encoded UTF-8 byte sequences. To decode + * it, use `sfparse_pctdecode`. * - * If :member:`vec.len ` == 0, :member:`vec.base - * ` is guaranteed to be NULL. + * If :member:`vec.len ` == 0, :member:`vec.base + * ` is guaranteed to be NULL. */ - sf_vec vec; + sfparse_vec vec; /** * @anonunion_end */ }; -} sf_value; +} sfparse_value; /** * @struct * - * :type:`sf_parser` is the Structured Field Values parser. Use - * `sf_parser_init` to initialize it. + * :type:`sfparse_parser` is the Structured Field Values parser. Use + * `sfparse_parser_init` to initialize it. */ -typedef struct sf_parser { +typedef struct sfparse_parser { /* all fields are private */ const uint8_t *pos; const uint8_t *end; uint32_t state; -} sf_parser; +} sfparse_parser; /** * @function * - * `sf_parser_init` initializes |sfp| with the given buffer pointed by - * |data| of length |datalen|. + * `sfparse_parser_init` initializes |sfp| with the given data encoded + * in Structured Field Values pointed by |data| of length |datalen|. */ -void sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen); +void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data, + size_t datalen); /** * @function * - * `sf_parser_param` reads a parameter. If this function returns 0, - * it stores parameter key and value in |dest_key| and |dest_value| + * `sfparse_parser_param` reads a parameter. If this function returns + * 0, it stores parameter key and value in |dest_key| and |dest_value| * respectively, if they are not NULL. * * This function does no effort to find duplicated keys. Same key may * be reported more than once. * * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SF_ERR_EOF`, all parameters have - * read, and caller can continue to read rest of the values. If it - * returns :macro:`SF_ERR_PARSE_ERROR`, it encountered fatal error + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all parameters + * have read, and caller can continue to read rest of the values. If + * it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error * while parsing field value. */ -int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value); +int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value); /** * @function * - * `sf_parser_dict` reads the next dictionary key and value pair. If - * this function returns 0, it stores the key and value in |dest_key| - * and |dest_value| respectively, if they are not NULL. + * `sfparse_parser_dict` reads the next dictionary key and value pair. + * If this function returns 0, it stores the key and value in + * |dest_key| and |dest_value| respectively, if they are not NULL. * * Caller can optionally read parameters attached to the pair by - * calling `sf_parser_param`. + * calling `sfparse_parser_param`. * * This function does no effort to find duplicated keys. Same key may * be reported more than once. * * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SF_ERR_EOF`, all key and value - * pairs have been read, and there is nothing left to read. + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all key and + * value pairs have been read, and there is nothing left to read. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :macro:`SF_ERR_EOF` + * :macro:`SFPARSE_ERR_EOF` * All values in the dictionary have read. - * :macro:`SF_ERR_PARSE_ERROR` + * :macro:`SFPARSE_ERR_PARSE` * It encountered fatal error while parsing field value. */ -int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value); +int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value); /** * @function * - * `sf_parser_list` reads the next list item. If this function + * `sfparse_parser_list` reads the next list item. If this function * returns 0, it stores the item in |dest| if it is not NULL. * * Caller can optionally read parameters attached to the item by - * calling `sf_parser_param`. + * calling `sfparse_parser_param`. * * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SF_ERR_EOF`, all values in the - * list have been read, and there is nothing left to read. + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in + * the list have been read, and there is nothing left to read. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :macro:`SF_ERR_EOF` + * :macro:`SFPARSE_ERR_EOF` * All values in the list have read. - * :macro:`SF_ERR_PARSE_ERROR` + * :macro:`SFPARSE_ERR_PARSE` * It encountered fatal error while parsing field value. */ -int sf_parser_list(sf_parser *sfp, sf_value *dest); +int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest); /** * @function * - * `sf_parser_item` reads a single item. If this function returns 0, - * it stores the item in |dest| if it is not NULL. + * `sfparse_parser_item` reads a single item. If this function + * returns 0, it stores the item in |dest| if it is not NULL. * * This function is only used for the field value that consists of a * single item. * * Caller can optionally read parameters attached to the item by - * calling `sf_parser_param`. + * calling `sfparse_parser_param`. * * Caller should call this function again to make sure that there is * nothing left to read. If this 2nd function call returns - * :macro:`SF_ERR_EOF`, all data have been processed successfully. + * :macro:`SFPARSE_ERR_EOF`, all data have been processed + * successfully. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :macro:`SF_ERR_EOF` + * :macro:`SFPARSE_ERR_EOF` * There is nothing left to read. - * :macro:`SF_ERR_PARSE_ERROR` + * :macro:`SFPARSE_ERR_PARSE` * It encountered fatal error while parsing field value. */ -int sf_parser_item(sf_parser *sfp, sf_value *dest); +int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest); /** * @function * - * `sf_parser_inner_list` reads the next inner list item. If this - * function returns 0, it stores the item in |dest| if it is not NULL. + * `sfparse_parser_inner_list` reads the next inner list item. If + * this function returns 0, it stores the item in |dest| if it is not + * NULL. * * Caller can optionally read parameters attached to the item by - * calling `sf_parser_param`. + * calling `sfparse_parser_param`. * * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SF_ERR_EOF`, all values in this - * inner list have been read, and caller can optionally read + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in + * this inner list have been read, and caller can optionally read * parameters attached to this inner list by calling - * `sf_parser_param`. Then caller can continue to read rest of the - * values. + * `sfparse_parser_param`. Then caller can continue to read rest of + * the values. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :macro:`SF_ERR_EOF` + * :macro:`SFPARSE_ERR_EOF` * All values in the inner list have read. - * :macro:`SF_ERR_PARSE_ERROR` + * :macro:`SFPARSE_ERR_PARSE` * It encountered fatal error while parsing field value. */ -int sf_parser_inner_list(sf_parser *sfp, sf_value *dest); +int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest); /** * @function * - * `sf_unescape` copies |src| to |dest| by removing escapes (``\``). - * |src| should be the pointer to :member:`sf_value.vec` of type - * :enum:`sf_type.SF_TYPE_STRING` produced by either `sf_parser_dict`, - * `sf_parser_list`, `sf_parser_inner_list`, `sf_parser_item`, or - * `sf_parser_param`, otherwise the behavior is undefined. + * `sfparse_unescape` copies |src| to |dest| by removing escapes + * (``\``). |src| should be the pointer to + * :member:`sfparse_value.vec` of type + * :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either + * `sfparse_parser_dict`, `sfparse_parser_list`, + * `sfparse_parser_inner_list`, `sfparse_parser_item`, or + * `sfparse_parser_param`, otherwise the behavior is undefined. * - * :member:`dest->base ` must point to the buffer that - * has sufficient space to store the unescaped string. + * :member:`dest->base ` must point to the buffer + * that has sufficient space to store the unescaped string. The + * memory areas pointed by :member:`dest->base ` and + * :member:`src->base ` must not overlap. * * This function sets the length of unescaped string to - * :member:`dest->len `. + * :member:`dest->len `. */ -void sf_unescape(sf_vec *dest, const sf_vec *src); +void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src); /** * @function * - * `sf_base64decode` decodes Base64 encoded string |src| and writes + * `sfparse_base64decode` decodes Base64 encoded string |src| and + * writes the result into |dest|. |src| should be the pointer to + * :member:`sfparse_value.vec` of type + * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either + * `sfparse_parser_dict`, `sfparse_parser_list`, + * `sfparse_parser_inner_list`, `sfparse_parser_item`, or + * `sfparse_parser_param`, otherwise the behavior is undefined. + * + * :member:`dest->base ` must point to the buffer + * that has sufficient space to store the decoded byte string. + * + * This function sets the length of decoded byte string to + * :member:`dest->len `. + */ +void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src); + +/** + * @function + * + * `sfparse_pctdecode` decodes percent-encoded string |src| and writes * the result into |dest|. |src| should be the pointer to - * :member:`sf_value.vec` of type :enum:`sf_type.SF_TYPE_BYTESEQ` - * produced by either `sf_parser_dict`, `sf_parser_list`, - * `sf_parser_inner_list`, `sf_parser_item`, or `sf_parser_param`, - * otherwise the behavior is undefined. + * :member:`sfparse_value.vec` of type + * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either + * `sfparse_parser_dict`, `sfparse_parser_list`, + * `sfparse_parser_inner_list`, `sfparse_parser_item`, or + * `sfparse_parser_param`, otherwise the behavior is undefined. * - * :member:`dest->base ` must point to the buffer that - * has sufficient space to store the decoded byte string. + * :member:`dest->base ` must point to the buffer + * that has sufficient space to store the decoded byte string. The + * memory areas pointed by :member:`dest->base ` and + * :member:`src->base ` must not overlap. * * This function sets the length of decoded byte string to - * :member:`dest->len `. + * :member:`dest->len `. */ -void sf_base64decode(sf_vec *dest, const sf_vec *src); - -/** - * @function - * - * `sf_pctdecode` decodes percent-encoded string |src| and writes the - * result into |dest|. |src| should be the pointer to - * :member:`sf_value.vec` of type :enum:`sf_type.SF_TYPE_DISPSTRING` - * produced by either `sf_parser_dict`, `sf_parser_list`, - * `sf_parser_inner_list`, `sf_parser_item`, or `sf_parser_param`, - * otherwise the behavior is undefined. - * - * :member:`dest->base ` must point to the buffer that - * has sufficient space to store the decoded byte string. - * - * This function sets the length of decoded byte string to - * :member:`dest->len `. - */ -void sf_pctdecode(sf_vec *dest, const sf_vec *src); +void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src); #ifdef __cplusplus } -#endif +#endif /* defined(__cplusplus) */ -#endif /* SFPARSE_H */ +#endif /* !defined(SFPARSE_H) */