diff --git a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h index ef40f1fa68498b..a6f486c5ab2da9 100644 --- a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h +++ b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h @@ -624,7 +624,7 @@ typedef struct nghttp3_buf { */ uint8_t *end; /** - * :member:`pos` pointers to the start of data. Typically, this + * :member:`pos` points to the start of data. Typically, this * points to the address that next data should be read. Initially, * it points to :member:`begin`. */ @@ -2198,6 +2198,9 @@ NGHTTP3_EXTERN int nghttp3_conn_add_write_offset(nghttp3_conn *conn, * If a stream denoted by |stream_id| is not found, this function * returns 0. * + * Alternatively, `nghttp3_conn_update_ack_offset` can be used to + * accomplish the same thing. + * * This function returns 0 if it succeeds, or one of the following * negative error codes: * @@ -2207,6 +2210,31 @@ NGHTTP3_EXTERN int nghttp3_conn_add_write_offset(nghttp3_conn *conn, NGHTTP3_EXTERN int nghttp3_conn_add_ack_offset(nghttp3_conn *conn, int64_t stream_id, uint64_t n); +/** + * @function + * + * `nghttp3_conn_update_ack_offset` tells |conn| that QUIC stack has + * acknowledged the stream data up to |offset| for a stream denoted by + * |stream_id|. + * + * If a stream denoted by |stream_id| is not found, this function + * returns 0. + * + * Alternatively, `nghttp3_conn_add_ack_offset` can be used to + * accomplish the same thing. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :macro:`NGHTTP3_ERR_INVALID_ARGUMENT` + * |offset| is less than the number of bytes acknowledged so far. + * :macro:`NGHTTP3_ERR_CALLBACK_FAILURE` + * User callback failed. + */ +NGHTTP3_EXTERN int nghttp3_conn_update_ack_offset(nghttp3_conn *conn, + int64_t stream_id, + uint64_t offset); + /** * @function * diff --git a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h index a71a49b18ff3a3..fc08316704016f 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.1.0" +#define NGHTTP3_VERSION "1.2.0" /** * @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 0x010100 +#define NGHTTP3_VERSION_NUM 0x010200 #endif /* NGHTTP3_VERSION_H */ diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c index 25aaf685734cb1..4606b0e04b2df5 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c @@ -2098,6 +2098,21 @@ int nghttp3_conn_add_ack_offset(nghttp3_conn *conn, int64_t stream_id, return nghttp3_stream_add_ack_offset(stream, n); } +int nghttp3_conn_update_ack_offset(nghttp3_conn *conn, int64_t stream_id, + uint64_t offset) { + nghttp3_stream *stream = nghttp3_conn_find_stream(conn, stream_id); + + if (stream == NULL) { + return 0; + } + + if (stream->ack_total > offset) { + return NGHTTP3_ERR_INVALID_ARGUMENT; + } + + return nghttp3_stream_add_ack_offset(stream, offset - stream->ack_total); +} + static int conn_submit_headers_data(nghttp3_conn *conn, nghttp3_stream *stream, const nghttp3_nv *nva, size_t nvlen, const nghttp3_data_reader *dr) { diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_http.c b/deps/ngtcp2/nghttp3/lib/nghttp3_http.c index 963134f13df946..fa97295843906c 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_http.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_http.c @@ -32,7 +32,7 @@ #include "nghttp3_macro.h" #include "nghttp3_conv.h" #include "nghttp3_unreachable.h" -#include "sfparse.h" +#include "sfparse/sfparse.h" static uint8_t downcase(uint8_t c) { return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h index 804969e14d6091..d743b19b441c87 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h @@ -880,19 +880,19 @@ int nghttp3_qpack_decoder_dtable_duplicate_add(nghttp3_qpack_decoder *decoder); int nghttp3_qpack_decoder_dtable_literal_add(nghttp3_qpack_decoder *decoder); struct nghttp3_qpack_stream_context { - /* state is a current state of reading request stream. */ - nghttp3_qpack_request_stream_state state; /* rstate is a set of intermediate state which are used to process request stream. */ nghttp3_qpack_read_state rstate; const nghttp3_mem *mem; - /* opcode is a request stream opcode being processed. */ - nghttp3_qpack_request_stream_opcode opcode; int64_t stream_id; /* ricnt is Required Insert Count to decode this header block. */ uint64_t ricnt; /* base is Base in Header Block Prefix. */ uint64_t base; + /* state is a current state of reading request stream. */ + nghttp3_qpack_request_stream_state state; + /* opcode is a request stream opcode being processed. */ + nghttp3_qpack_request_stream_opcode opcode; /* dbase_sign is the delta base sign in Header Block Prefix. */ int dbase_sign; }; diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c index 6188a141dd123b..6213a2074ac10c 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.c @@ -979,6 +979,7 @@ int nghttp3_stream_add_ack_offset(nghttp3_stream *stream, uint64_t n) { } stream->ack_offset = offset; + stream->ack_total += n; return 0; } diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h index 03a57697b232b3..a632537330fc20 100644 --- a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h +++ b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h @@ -88,8 +88,8 @@ typedef struct nghttp3_varint_read_state { typedef struct nghttp3_stream_read_state { nghttp3_varint_read_state rvint; nghttp3_frame fr; - int state; int64_t left; + int state; } nghttp3_stream_read_state; /* NGHTTP3_STREAM_FLAG_NONE indicates that no flag is set. */ @@ -186,9 +186,6 @@ typedef struct nghttp3_stream_callbacks { } nghttp3_stream_callbacks; typedef struct nghttp3_http_state { - /* status_code is HTTP status code received. This field is used - if connection is initialized as client. */ - int32_t status_code; /* content_length is the value of received content-length header field. */ int64_t content_length; @@ -196,6 +193,9 @@ typedef struct nghttp3_http_state { far. */ int64_t recv_content_length; nghttp3_pri pri; + /* status_code is HTTP status code received. This field is used + if connection is initialized as client. */ + int32_t status_code; uint32_t flags; } nghttp3_http_state; @@ -233,6 +233,9 @@ struct nghttp3_stream { they are acknowledged inside the first outq element if it is of type NGHTTP3_BUF_TYPE_ALIEN. */ uint64_t ack_done; + /* ack_total is the cumulative number of bytes acknowledged so + far. */ + uint64_t ack_total; uint64_t unscheduled_nwrite; nghttp3_stream_type type; nghttp3_stream_read_state rstate; diff --git a/deps/ngtcp2/nghttp3/lib/sfparse.c b/deps/ngtcp2/nghttp3/lib/sfparse.c deleted file mode 100644 index efa2850c9d661d..00000000000000 --- a/deps/ngtcp2/nghttp3/lib/sfparse.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* - * sfparse - * - * Copyright (c) 2023 sfparse contributors - * Copyright (c) 2019 nghttp3 contributors - * Copyright (c) 2015 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "sfparse.h" - -#include -#include -#include - -#define SF_STATE_DICT 0x08u -#define SF_STATE_LIST 0x10u -#define SF_STATE_ITEM 0x18u - -#define SF_STATE_INNER_LIST 0x04u - -#define SF_STATE_BEFORE 0x00u -#define SF_STATE_BEFORE_PARAMS 0x01u -#define SF_STATE_PARAMS 0x02u -#define SF_STATE_AFTER 0x03u - -#define SF_STATE_OP_MASK 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 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 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 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 SF_STATE_INITIAL 0x00u - -#define DIGIT_CASES \ - case '0': \ - case '1': \ - case '2': \ - case '3': \ - case '4': \ - case '5': \ - case '6': \ - case '7': \ - case '8': \ - case '9' - -#define LCALPHA_CASES \ - case 'a': \ - case 'b': \ - case 'c': \ - case 'd': \ - case 'e': \ - case 'f': \ - case 'g': \ - case 'h': \ - case 'i': \ - case 'j': \ - case 'k': \ - case 'l': \ - case 'm': \ - case 'n': \ - case 'o': \ - case 'p': \ - case 'q': \ - case 'r': \ - case 's': \ - case 't': \ - case 'u': \ - case 'v': \ - case 'w': \ - case 'x': \ - case 'y': \ - case 'z' - -#define UCALPHA_CASES \ - case 'A': \ - case 'B': \ - case 'C': \ - case 'D': \ - case 'E': \ - case 'F': \ - case 'G': \ - case 'H': \ - case 'I': \ - case 'J': \ - case 'K': \ - case 'L': \ - case 'M': \ - case 'N': \ - case 'O': \ - case 'P': \ - case 'Q': \ - case 'R': \ - case 'S': \ - case 'T': \ - case 'U': \ - case 'V': \ - case 'W': \ - case 'X': \ - case 'Y': \ - case 'Z' - -#define ALPHA_CASES \ - UCALPHA_CASES: \ - LCALPHA_CASES - -#define X20_21_CASES \ - case ' ': \ - case '!' - -#define X23_5B_CASES \ - case '#': \ - case '$': \ - case '%': \ - case '&': \ - case '\'': \ - case '(': \ - case ')': \ - case '*': \ - case '+': \ - case ',': \ - case '-': \ - case '.': \ - case '/': \ - DIGIT_CASES: \ - case ':': \ - case ';': \ - case '<': \ - case '=': \ - case '>': \ - case '?': \ - case '@': \ - UCALPHA_CASES: \ - case '[' - -#define X5D_7E_CASES \ - case ']': \ - case '^': \ - case '_': \ - case '`': \ - LCALPHA_CASES: \ - case '{': \ - case '|': \ - case '}': \ - case '~' - -static int is_ws(uint8_t c) { - switch (c) { - case ' ': - case '\t': - return 1; - default: - return 0; - } -} - -static int parser_eof(sf_parser *sfp) { return sfp->pos == sfp->end; } - -static void parser_discard_ows(sf_parser *sfp) { - for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos) - ; -} - -static void parser_discard_sp(sf_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; - sfp->state |= op; -} - -static void parser_unset_inner_list_state(sf_parser *sfp) { - sfp->state &= ~SF_STATE_INNER_LIST; -} - -static int parser_key(sf_parser *sfp, sf_vec *dest) { - const uint8_t *base; - - switch (*sfp->pos) { - case '*': - LCALPHA_CASES: - break; - default: - return SF_ERR_PARSE_ERROR; - } - - base = sfp->pos++; - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - case '_': - case '-': - case '.': - case '*': - DIGIT_CASES: - LCALPHA_CASES: - continue; - } - - break; - } - - if (dest) { - dest->base = (uint8_t *)base; - dest->len = (size_t)(sfp->pos - dest->base); - } - - return 0; -} - -static int parser_number(sf_parser *sfp, sf_value *dest) { - int sign = 1; - int64_t value = 0; - size_t len = 0; - size_t fpos = 0; - - if (*sfp->pos == '-') { - ++sfp->pos; - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - sign = -1; - } - - assert(!parser_eof(sfp)); - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - DIGIT_CASES: - if (++len > 15) { - return SF_ERR_PARSE_ERROR; - } - - value *= 10; - value += *sfp->pos - '0'; - - continue; - } - - break; - } - - if (len == 0) { - return SF_ERR_PARSE_ERROR; - } - - if (parser_eof(sfp) || *sfp->pos != '.') { - if (dest) { - dest->type = SF_TYPE_INTEGER; - dest->flags = SF_VALUE_FLAG_NONE; - dest->integer = value * sign; - } - - return 0; - } - - /* decimal */ - - if (len > 12) { - return SF_ERR_PARSE_ERROR; - } - - fpos = len; - - ++sfp->pos; - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - DIGIT_CASES: - if (++len > 15) { - return SF_ERR_PARSE_ERROR; - } - - value *= 10; - value += *sfp->pos - '0'; - - continue; - } - - break; - } - - if (fpos == len || len - fpos > 3) { - return SF_ERR_PARSE_ERROR; - } - - if (dest) { - dest->type = SF_TYPE_DECIMAL; - dest->flags = SF_VALUE_FLAG_NONE; - dest->decimal.numer = value * sign; - - switch (len - fpos) { - case 1: - dest->decimal.denom = 10; - - break; - case 2: - dest->decimal.denom = 100; - - break; - case 3: - dest->decimal.denom = 1000; - - break; - } - } - - return 0; -} - -static int parser_date(sf_parser *sfp, sf_value *dest) { - int rv; - sf_value val; - - /* The first byte has already been validated by the caller. */ - assert('@' == *sfp->pos); - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - rv = parser_number(sfp, &val); - if (rv != 0) { - return rv; - } - - if (val.type != SF_TYPE_INTEGER) { - return SF_ERR_PARSE_ERROR; - } - - if (dest) { - *dest = val; - dest->type = SF_TYPE_DATE; - } - - return 0; -} - -static int parser_string(sf_parser *sfp, sf_value *dest) { - const uint8_t *base; - uint32_t flags = SF_VALUE_FLAG_NONE; - - /* The first byte has already been validated by the caller. */ - assert('"' == *sfp->pos); - - base = ++sfp->pos; - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - X20_21_CASES: - X23_5B_CASES: - X5D_7E_CASES: - break; - case '\\': - ++sfp->pos; - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - switch (*sfp->pos) { - case '"': - case '\\': - flags = SF_VALUE_FLAG_ESCAPED_STRING; - - break; - default: - return SF_ERR_PARSE_ERROR; - } - - 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; - default: - return SF_ERR_PARSE_ERROR; - } - } - - return SF_ERR_PARSE_ERROR; -} - -static int parser_token(sf_parser *sfp, sf_value *dest) { - const uint8_t *base; - - /* The first byte has already been validated by the caller. */ - base = sfp->pos++; - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - case '!': - case '#': - case '$': - case '%': - case '&': - case '\'': - case '*': - case '+': - case '-': - case '.': - case '^': - case '_': - case '`': - case '|': - case '~': - case ':': - case '/': - DIGIT_CASES: - ALPHA_CASES: - continue; - } - - break; - } - - if (dest) { - dest->type = SF_TYPE_TOKEN; - dest->flags = SF_VALUE_FLAG_NONE; - dest->vec.base = (uint8_t *)base; - dest->vec.len = (size_t)(sfp->pos - base); - } - - return 0; -} - -static int parser_byteseq(sf_parser *sfp, sf_value *dest) { - const uint8_t *base; - - /* The first byte has already been validated by the caller. */ - assert(':' == *sfp->pos); - - base = ++sfp->pos; - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - case '+': - case '/': - DIGIT_CASES: - ALPHA_CASES: - continue; - case '=': - switch ((sfp->pos - base) & 0x3) { - case 0: - case 1: - return SF_ERR_PARSE_ERROR; - case 2: - switch (*(sfp->pos - 1)) { - case 'A': - case 'Q': - case 'g': - case 'w': - break; - default: - return SF_ERR_PARSE_ERROR; - } - - ++sfp->pos; - - if (parser_eof(sfp) || *sfp->pos != '=') { - return SF_ERR_PARSE_ERROR; - } - - break; - case 3: - switch (*(sfp->pos - 1)) { - case 'A': - case 'E': - case 'I': - case 'M': - case 'Q': - case 'U': - case 'Y': - case 'c': - case 'g': - case 'k': - case 'o': - case 's': - case 'w': - case '0': - case '4': - case '8': - break; - default: - return SF_ERR_PARSE_ERROR; - } - - break; - } - - ++sfp->pos; - - if (parser_eof(sfp) || *sfp->pos != ':') { - return SF_ERR_PARSE_ERROR; - } - - goto fin; - case ':': - if ((sfp->pos - base) & 0x3) { - return SF_ERR_PARSE_ERROR; - } - - goto fin; - default: - return SF_ERR_PARSE_ERROR; - } - } - - return SF_ERR_PARSE_ERROR; - -fin: - if (dest) { - dest->type = SF_TYPE_BYTESEQ; - dest->flags = SF_VALUE_FLAG_NONE; - 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_boolean(sf_parser *sfp, sf_value *dest) { - int b; - - /* The first byte has already been validated by the caller. */ - assert('?' == *sfp->pos); - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - switch (*sfp->pos) { - case '0': - b = 0; - - break; - case '1': - b = 1; - - break; - default: - return SF_ERR_PARSE_ERROR; - } - - ++sfp->pos; - - if (dest) { - dest->type = SF_TYPE_BOOLEAN; - dest->flags = SF_VALUE_FLAG_NONE; - dest->boolean = b; - } - - return 0; -} - -static int parser_bare_item(sf_parser *sfp, sf_value *dest) { - switch (*sfp->pos) { - case '"': - return parser_string(sfp, dest); - case '-': - DIGIT_CASES: - return parser_number(sfp, dest); - case '@': - return parser_date(sfp, dest); - case ':': - return parser_byteseq(sfp, dest); - case '?': - return parser_boolean(sfp, dest); - case '*': - ALPHA_CASES: - return parser_token(sfp, dest); - default: - return SF_ERR_PARSE_ERROR; - } -} - -static int parser_skip_inner_list(sf_parser *sfp); - -int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { - int rv; - - switch (sfp->state & SF_STATE_OP_MASK) { - case SF_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); - - break; - case SF_STATE_PARAMS: - break; - default: - assert(0); - abort(); - } - - if (parser_eof(sfp) || *sfp->pos != ';') { - parser_set_op_state(sfp, SF_STATE_AFTER); - - return SF_ERR_EOF; - } - - ++sfp->pos; - - parser_discard_sp(sfp); - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - rv = parser_key(sfp, dest_key); - if (rv != 0) { - return rv; - } - - if (parser_eof(sfp) || *sfp->pos != '=') { - if (dest_value) { - dest_value->type = SF_TYPE_BOOLEAN; - dest_value->flags = SF_VALUE_FLAG_NONE; - dest_value->boolean = 1; - } - - return 0; - } - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - return parser_bare_item(sfp, dest_value); -} - -static int parser_skip_params(sf_parser *sfp) { - int rv; - - for (;;) { - rv = sf_parser_param(sfp, NULL, NULL); - switch (rv) { - case 0: - break; - case SF_ERR_EOF: - return 0; - case SF_ERR_PARSE_ERROR: - return rv; - default: - assert(0); - abort(); - } - } -} - -int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) { - int rv; - - switch (sfp->state & SF_STATE_OP_MASK) { - case SF_STATE_BEFORE: - parser_discard_sp(sfp); - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - break; - case SF_STATE_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* Technically, we are entering SF_STATE_AFTER, but we will set - another state without reading the state. */ - /* parser_set_op_state(sfp, SF_STATE_AFTER); */ - - /* fall through */ - case SF_STATE_AFTER: - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - switch (*sfp->pos) { - case ' ': - parser_discard_sp(sfp); - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - break; - case ')': - break; - default: - return SF_ERR_PARSE_ERROR; - } - - break; - default: - assert(0); - abort(); - } - - if (*sfp->pos == ')') { - ++sfp->pos; - - parser_unset_inner_list_state(sfp); - parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS); - - return SF_ERR_EOF; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS); - - return 0; -} - -static int parser_skip_inner_list(sf_parser *sfp) { - int rv; - - for (;;) { - rv = sf_parser_inner_list(sfp, NULL); - switch (rv) { - case 0: - break; - case SF_ERR_EOF: - return 0; - case SF_ERR_PARSE_ERROR: - return rv; - default: - assert(0); - abort(); - } - } -} - -static int parser_next_key_or_item(sf_parser *sfp) { - parser_discard_ows(sfp); - - if (parser_eof(sfp)) { - return SF_ERR_EOF; - } - - if (*sfp->pos != ',') { - return SF_ERR_PARSE_ERROR; - } - - ++sfp->pos; - - parser_discard_ows(sfp); - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - return 0; -} - -static int parser_dict_value(sf_parser *sfp, sf_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->boolean = 1; - } - - sfp->state = SF_STATE_DICT_BEFORE_PARAMS; - - return 0; - } - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - if (*sfp->pos == '(') { - if (dest) { - dest->type = SF_TYPE_INNER_LIST; - dest->flags = SF_VALUE_FLAG_NONE; - } - - ++sfp->pos; - - sfp->state = SF_STATE_DICT_INNER_LIST_BEFORE; - - return 0; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - sfp->state = SF_STATE_DICT_BEFORE_PARAMS; - - return 0; -} - -int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { - int rv; - - switch (sfp->state) { - case SF_STATE_DICT_INNER_LIST_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SF_STATE_DICT_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SF_STATE_DICT_AFTER: - rv = parser_next_key_or_item(sfp); - if (rv != 0) { - return rv; - } - - break; - case SF_STATE_INITIAL: - parser_discard_sp(sfp); - - if (parser_eof(sfp)) { - return SF_ERR_EOF; - } - - break; - default: - assert(0); - abort(); - } - - rv = parser_key(sfp, dest_key); - if (rv != 0) { - return rv; - } - - return parser_dict_value(sfp, dest_value); -} - -int sf_parser_list(sf_parser *sfp, sf_value *dest) { - int rv; - - switch (sfp->state) { - case SF_STATE_LIST_INNER_LIST_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SF_STATE_LIST_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SF_STATE_LIST_AFTER: - rv = parser_next_key_or_item(sfp); - if (rv != 0) { - return rv; - } - - break; - case SF_STATE_INITIAL: - parser_discard_sp(sfp); - - if (parser_eof(sfp)) { - return SF_ERR_EOF; - } - - break; - default: - assert(0); - abort(); - } - - if (*sfp->pos == '(') { - if (dest) { - dest->type = SF_TYPE_INNER_LIST; - dest->flags = SF_VALUE_FLAG_NONE; - } - - ++sfp->pos; - - sfp->state = SF_STATE_LIST_INNER_LIST_BEFORE; - - return 0; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - sfp->state = SF_STATE_LIST_BEFORE_PARAMS; - - return 0; -} - -int sf_parser_item(sf_parser *sfp, sf_value *dest) { - int rv; - - switch (sfp->state) { - case SF_STATE_INITIAL: - parser_discard_sp(sfp); - - if (parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - break; - case SF_STATE_ITEM_INNER_LIST_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SF_STATE_ITEM_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SF_STATE_ITEM_AFTER: - parser_discard_sp(sfp); - - if (!parser_eof(sfp)) { - return SF_ERR_PARSE_ERROR; - } - - return SF_ERR_EOF; - default: - assert(0); - abort(); - } - - if (*sfp->pos == '(') { - if (dest) { - dest->type = SF_TYPE_INNER_LIST; - dest->flags = SF_VALUE_FLAG_NONE; - } - - ++sfp->pos; - - sfp->state = SF_STATE_ITEM_INNER_LIST_BEFORE; - - return 0; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - sfp->state = SF_STATE_ITEM_BEFORE_PARAMS; - - return 0; -} - -void sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen) { - if (datalen == 0) { - sfp->pos = sfp->end = NULL; - } else { - sfp->pos = data; - sfp->end = data + datalen; - } - - sfp->state = SF_STATE_INITIAL; -} - -void sf_unescape(sf_vec *dest, const sf_vec *src) { - const uint8_t *p, *q; - uint8_t *o; - size_t len, slen; - - if (src->len == 0) { - *dest = *src; - - return; - } - - o = dest->base; - p = src->base; - len = src->len; - - for (;;) { - q = memchr(p, '\\', len); - if (q == NULL) { - if (len == src->len) { - *dest = *src; - - return; - } - - memcpy(o, p, len); - o += len; - - break; - } - - slen = (size_t)(q - p); - memcpy(o, p, slen); - o += slen; - - p = q + 1; - *o++ = *p++; - len -= slen + 2; - } - - dest->len = (size_t)(o - dest->base); -} - -void sf_base64decode(sf_vec *dest, const sf_vec *src) { - static const int index_tbl[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1}; - uint8_t *o; - const uint8_t *p, *end; - uint32_t n; - size_t i; - int idx; - - assert((src->len & 0x3) == 0); - - if (src->len == 0) { - *dest = *src; - - return; - } - - o = dest->base; - p = src->base; - end = src->base + src->len; - - for (; p != end;) { - n = 0; - - for (i = 1; i <= 4; ++i, ++p) { - idx = index_tbl[*p]; - - if (idx == -1) { - assert(i > 2); - - if (i == 3) { - assert(*p == '=' && *(p + 1) == '=' && p + 2 == end); - - *o++ = (uint8_t)(n >> 16); - - goto fin; - } - - assert(*p == '=' && p + 1 == end); - - *o++ = (uint8_t)(n >> 16); - *o++ = (n >> 8) & 0xffu; - - goto fin; - } - - n += (uint32_t)(idx << (24 - i * 6)); - } - - *o++ = (uint8_t)(n >> 16); - *o++ = (n >> 8) & 0xffu; - *o++ = n & 0xffu; - } - -fin: - dest->len = (size_t)(o - dest->base); -} diff --git a/deps/ngtcp2/nghttp3/lib/sfparse.h b/deps/ngtcp2/nghttp3/lib/sfparse.h deleted file mode 100644 index 1474db1429acea..00000000000000 --- a/deps/ngtcp2/nghttp3/lib/sfparse.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * sfparse - * - * Copyright (c) 2023 sfparse contributors - * Copyright (c) 2019 nghttp3 contributors - * Copyright (c) 2015 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef SFPARSE_H -#define SFPARSE_H - -/* Define WIN32 when build target is Win32 API (borrowed from - libcurl) */ -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#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) */ -# include -#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ -#include -#include - -/** - * @enum - * - * :type:`sf_type` defines value type. - */ -typedef enum sf_type { - /** - * :enum:`SF_TYPE_BOOLEAN` indicates boolean type. - */ - SF_TYPE_BOOLEAN, - /** - * :enum:`SF_TYPE_INTEGER` indicates integer type. - */ - SF_TYPE_INTEGER, - /** - * :enum:`SF_TYPE_DECIMAL` indicates decimal type. - */ - SF_TYPE_DECIMAL, - /** - * :enum:`SF_TYPE_STRING` indicates string type. - */ - SF_TYPE_STRING, - /** - * :enum:`SF_TYPE_TOKEN` indicates token type. - */ - SF_TYPE_TOKEN, - /** - * :enum:`SF_TYPE_BYTESEQ` indicates byte sequence type. - */ - SF_TYPE_BYTESEQ, - /** - * :enum:`SF_TYPE_INNER_LIST` indicates inner list type. - */ - SF_TYPE_INNER_LIST, - /** - * :enum:`SF_TYPE_DATE` indicates date type. - */ - SF_TYPE_DATE -} sf_type; - -/** - * @macro - * - * :macro:`SF_ERR_PARSE_ERROR` indicates fatal parse error has - * occurred, and it is not possible to continue the processing. - */ -#define SF_ERR_PARSE_ERROR -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. - */ -#define SF_ERR_EOF -2 - -/** - * @struct - * - * :type:`sf_vec` stores sequence of bytes. - */ -typedef struct sf_vec { - /** - * :member:`base` points to the beginning of the sequence of bytes. - */ - uint8_t *base; - /** - * :member:`len` is the number of bytes contained in this sequence. - */ - size_t len; -} sf_vec; - -/** - * @macro - * - * :macro:`SF_VALUE_FLAG_NONE` indicates no flag set. - */ -#define SF_VALUE_FLAG_NONE 0x0u - -/** - * @macro - * - * :macro:`SF_VALUE_FLAG_ESCAPED_STRING` indicates that a string - * contains escaped character(s). - */ -#define SF_VALUE_FLAG_ESCAPED_STRING 0x1u - -/** - * @struct - * - * :type:`sf_decimal` contains decimal value. - */ -typedef struct sf_decimal { - /** - * :member:`numer` contains numerator of the decimal value. - */ - int64_t numer; - /** - * :member:`denom` contains denominator of the decimal value. - */ - int64_t denom; -} sf_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`. - */ -typedef struct sf_value { - /** - * :member:`type` is the type of the value contained in this - * particular object. - */ - sf_type type; - /** - * :member:`flags` is bitwise OR of one or more of - * :macro:`SF_VALUE_FLAG_* `. - */ - uint32_t flags; - /** - * @anonunion_start - * - * @sf_value_value - */ - union { - /** - * :member:`boolean` contains boolean value if :member:`type` == - * :enum:`sf_type.SF_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`. - */ - int64_t integer; - /** - * :member:`decimal` contains decimal value if :member:`type` == - * :enum:`sf_type.SF_TYPE_DECIMAL`. - */ - sf_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`, or - * :enum:`sf_type.SF_TYPE_BYTESEQ`. - * - * 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:`sf_type.SF_TYPE_BYTESEQ`, this field contains base64 - * encoded string. To decode this byte string, use - * `sf_base64decode`. - * - * If :member:`vec.len ` == 0, :member:`vec.base - * ` is guaranteed to be NULL. - */ - sf_vec vec; - /** - * @anonunion_end - */ - }; -} sf_value; - -/** - * @struct - * - * :type:`sf_parser` is the Structured Field Values parser. Use - * `sf_parser_init` to initialize it. - */ -typedef struct sf_parser { - /* all fields are private */ - const uint8_t *pos; - const uint8_t *end; - uint32_t state; -} sf_parser; - -/** - * @function - * - * `sf_parser_init` initializes |sfp| with the given buffer pointed by - * |data| of length |datalen|. - */ -void sf_parser_init(sf_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| - * 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 - * while parsing field value. - */ -int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_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. - * - * Caller can optionally read parameters attached to the pair by - * calling `sf_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. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SF_ERR_EOF` - * All values in the dictionary have read. - * :macro:`SF_ERR_PARSE_ERROR` - * It encountered fatal error while parsing field value. - */ -int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value); - -/** - * @function - * - * `sf_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`. - * - * 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. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SF_ERR_EOF` - * All values in the list have read. - * :macro:`SF_ERR_PARSE_ERROR` - * It encountered fatal error while parsing field value. - */ -int sf_parser_list(sf_parser *sfp, sf_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. - * - * 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`. - * - * 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. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SF_ERR_EOF` - * There is nothing left to read. - * :macro:`SF_ERR_PARSE_ERROR` - * It encountered fatal error while parsing field value. - */ -int sf_parser_item(sf_parser *sfp, sf_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. - * - * Caller can optionally read parameters attached to the item by - * calling `sf_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 - * parameters attached to this inner list by calling - * `sf_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` - * All values in the inner list have read. - * :macro:`SF_ERR_PARSE_ERROR` - * It encountered fatal error while parsing field value. - */ -int sf_parser_inner_list(sf_parser *sfp, sf_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. - * - * :member:`dest->base ` must point to the buffer that - * has sufficient space to store the unescaped string. - * - * If there is no escape character in |src|, |*src| is assigned to - * |*dest|. This includes the case that :member:`src->len - * ` == 0. - * - * This function sets the length of unescaped string to - * :member:`dest->len `. - */ -void sf_unescape(sf_vec *dest, const sf_vec *src); - -/** - * @function - * - * `sf_base64decode` decodes Base64 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:`dest->base ` must point to the buffer that - * has sufficient space to store the decoded byte string. - * - * If :member:`src->len ` == 0, |*src| is assigned to - * |*dest|. - * - * This function sets the length of decoded byte string to - * :member:`dest->len `. - */ -void sf_base64decode(sf_vec *dest, const sf_vec *src); - -#ifdef __cplusplus -} -#endif - -#endif /* SFPARSE_H */