diff --git a/.gitignore b/.gitignore index e062c27..b1b4b22 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -icu4c-76_1-data-bin-b.zip -icu4c-76_1-data-bin-l.zip -node-v22.13.1-stripped.tar.gz +icu4c-78.2-data-bin-b.zip +icu4c-78.2-data-bin-l.zip +node-v22.22.2-stripped.tar.gz diff --git a/0001-CVE-2026-25547-braces-expansion.patch b/0001-CVE-2026-25547-braces-expansion.patch new file mode 100644 index 0000000..726ec71 --- /dev/null +++ b/0001-CVE-2026-25547-braces-expansion.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: tjuhasz +Date: Tue, 25 Feb 2026 14:21:26 +0100 +Subject: [PATCH] CVE-2026-25547: Fix brace expansion vulnerability + +Add expansion limit to prevent DoS attacks through excessive +brace expansion in the brace-expansion module. + +--- + deps/npm/node_modules/brace-expansion/index.js | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/deps/npm/node_modules/brace-expansion/index.js b/deps/npm/node_modules/brace-expansion/index.js +--- a/deps/npm/node_modules/brace-expansion/index.js 2026-01-12 23:55:24.000000000 +0100 ++++ b/deps/npm/node_modules/brace-expansion/index.js 2026-02-25 14:21:26.829483831 +0100 +@@ -8,6 +8,8 @@ + var escComma = '\0COMMA'+Math.random()+'\0'; + var escPeriod = '\0PERIOD'+Math.random()+'\0'; + ++const EXPANSION_MAX = 100_000; ++ + function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) +@@ -61,9 +63,11 @@ + return parts; + } + +-function expandTop(str) { ++function expandTop(str, options = {}) { + if (!str) + return []; ++ ++ const { max = EXPANSION_MAX } = options; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved +@@ -75,7 +79,7 @@ + str = '\\{\\}' + str.substr(2); + } + +- return expand(escapeBraces(str), true).map(unescapeBraces); ++ return expand(escapeBraces(str), max, true).map(unescapeBraces); + } + + function embrace(str) { +@@ -92,7 +96,7 @@ + return i >= y; + } + +-function expand(str, isTop) { ++function expand(str, max, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); +@@ -101,11 +105,11 @@ + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length +- ? expand(m.post, false) ++ ? expand(m.post, max, false) + : ['']; + + if (/\$$/.test(m.pre)) { +- for (var k = 0; k < post.length; k++) { ++ for (var k = 0; k < post.length && k < max; k++) { + var expansion = pre+ '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } +@@ -118,7 +122,7 @@ + // {a},b} + if (m.post.match(/,(?!,).*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; +- return expand(str); ++ return expand(str, max, true); + } + return [str]; + } +@@ -130,7 +134,7 @@ + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y +- n = expand(n[0], false).map(embrace); ++ n = expand(n[0], max, false).map(embrace); + if (n.length === 1) { + return post.map(function(p) { + return m.pre + n[0] + p; +@@ -185,12 +189,12 @@ + N = []; + + for (var j = 0; j < n.length; j++) { +- N.push.apply(N, expand(n[j], false)); ++ N.push.apply(N, expand(n[j], max, false)); + } + } + + for (var j = 0; j < N.length; j++) { +- for (var k = 0; k < post.length; k++) { ++ for (var k = 0; k < post.length && expansions.length < max; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); diff --git a/0001-deps-update-nghttp2-to-1.68.1.patch b/0001-deps-update-nghttp2-to-1.68.1.patch new file mode 100644 index 0000000..31843ed --- /dev/null +++ b/0001-deps-update-nghttp2-to-1.68.1.patch @@ -0,0 +1,7712 @@ +From 6c2d85acee9efe29348068eadb38c8fec4f04ed0 Mon Sep 17 00:00:00 2001 +From: Andrei Radchenko +Date: Thu, 26 Mar 2026 08:58:20 +0100 +Subject: [PATCH] deps: update nghttp2 to 1.68.1 + +--- + deps/nghttp2/lib/CMakeLists.txt | 40 +- + deps/nghttp2/lib/Makefile.am | 2 +- + deps/nghttp2/lib/Makefile.in | 6 +- + deps/nghttp2/lib/config.cmake.in | 3 + + deps/nghttp2/lib/includes/Makefile.in | 4 + + deps/nghttp2/lib/includes/nghttp2/nghttp2.h | 315 ++--- + .../nghttp2/lib/includes/nghttp2/nghttp2ver.h | 4 +- + deps/nghttp2/lib/nghttp2_alpn.h | 4 +- + deps/nghttp2/lib/nghttp2_buf.h | 4 +- + deps/nghttp2/lib/nghttp2_callbacks.c | 5 + + deps/nghttp2/lib/nghttp2_callbacks.h | 5 +- + deps/nghttp2/lib/nghttp2_debug.c | 4 +- + deps/nghttp2/lib/nghttp2_debug.h | 8 +- + deps/nghttp2/lib/nghttp2_extpri.h | 4 +- + deps/nghttp2/lib/nghttp2_frame.c | 10 + + deps/nghttp2/lib/nghttp2_frame.h | 4 +- + deps/nghttp2/lib/nghttp2_hd.c | 11 + + deps/nghttp2/lib/nghttp2_hd.h | 4 +- + deps/nghttp2/lib/nghttp2_hd_huffman.h | 4 +- + deps/nghttp2/lib/nghttp2_helper.h | 4 +- + deps/nghttp2/lib/nghttp2_http.c | 17 +- + deps/nghttp2/lib/nghttp2_http.h | 4 +- + deps/nghttp2/lib/nghttp2_int.h | 10 +- + deps/nghttp2/lib/nghttp2_map.c | 70 +- + deps/nghttp2/lib/nghttp2_map.h | 9 +- + deps/nghttp2/lib/nghttp2_mem.h | 4 +- + deps/nghttp2/lib/nghttp2_net.h | 16 +- + deps/nghttp2/lib/nghttp2_option.c | 7 + + deps/nghttp2/lib/nghttp2_option.h | 10 +- + deps/nghttp2/lib/nghttp2_outbound_item.h | 4 +- + deps/nghttp2/lib/nghttp2_pq.h | 4 +- + deps/nghttp2/lib/nghttp2_priority_spec.h | 4 +- + deps/nghttp2/lib/nghttp2_queue.h | 4 +- + deps/nghttp2/lib/nghttp2_ratelim.h | 4 +- + deps/nghttp2/lib/nghttp2_rcbuf.h | 4 +- + deps/nghttp2/lib/nghttp2_session.c | 1163 ++++++----------- + deps/nghttp2/lib/nghttp2_session.h | 147 +-- + deps/nghttp2/lib/nghttp2_stream.c | 847 +----------- + deps/nghttp2/lib/nghttp2_stream.h | 161 +-- + deps/nghttp2/lib/nghttp2_submit.c | 164 +-- + deps/nghttp2/lib/nghttp2_submit.h | 4 +- + deps/nghttp2/lib/nghttp2_time.c | 15 +- + deps/nghttp2/lib/nghttp2_time.h | 4 +- + deps/nghttp2/lib/nghttp2_version.c | 2 +- + deps/nghttp2/lib/sfparse.c | 1140 ++++++++++++---- + deps/nghttp2/lib/sfparse.h | 313 +++-- + 46 files changed, 1834 insertions(+), 2742 deletions(-) + create mode 100644 deps/nghttp2/lib/config.cmake.in + +diff --git a/deps/nghttp2/lib/CMakeLists.txt b/deps/nghttp2/lib/CMakeLists.txt +index fda8dcb7..98e3dbe7 100644 +--- a/deps/nghttp2/lib/CMakeLists.txt ++++ b/deps/nghttp2/lib/CMakeLists.txt +@@ -47,7 +47,29 @@ if(WIN32) + set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + endif() + +-set(EXPORT_SET "${PROJECT_NAME}-targets") ++set(NGHTTP2_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") ++set(NGHTTP2_VERSION_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake") ++set(NGHTTP2_PROJECT_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}Config.cmake") ++set(NGHTTP2_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") ++set(NGHTTP2_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}") ++set(NGHTTP2_NAMESPACE "${PROJECT_NAME}::") ++set(NGHTTP2_VERSION ${PROJECT_VERSION}) ++ ++include(CMakePackageConfigHelpers) ++write_basic_package_version_file( ++ "${NGHTTP2_VERSION_CONFIG}" VERSION ${NGHTTP2_VERSION} COMPATIBILITY SameMajorVersion ++) ++configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in" "${NGHTTP2_PROJECT_CONFIG}" @ONLY) ++ ++# Install cmake config files ++install( ++ FILES "${NGHTTP2_PROJECT_CONFIG}" "${NGHTTP2_VERSION_CONFIG}" ++ DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}") ++ ++install( ++ EXPORT "${NGHTTP2_TARGETS_EXPORT_NAME}" ++ NAMESPACE "${NGHTTP2_NAMESPACE}" ++ DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}") + + # Public shared library + if(BUILD_SHARED_LIBS) +@@ -65,7 +87,11 @@ if(BUILD_SHARED_LIBS) + $ + ) + +- install(TARGETS ${SHARED_LIB} EXPORT ${EXPORT_SET}) ++ install(TARGETS ${SHARED_LIB} ++ EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME} ++ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" ++ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ++ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + list(APPEND nghttp2_exports ${SHARED_LIB}) + endif() + +@@ -87,7 +113,9 @@ if(BUILD_STATIC_LIBS) + + target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB") + +- install(TARGETS ${STATIC_LIB} EXPORT ${EXPORT_SET}) ++ install(TARGETS ${STATIC_LIB} ++ EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME} ++ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") + list(APPEND nghttp2_exports ${STATIC_LIB}) + endif() + +@@ -97,11 +125,7 @@ else() + set(LIB_SELECTED ${STATIC_LIB}) + endif() + +-add_library(${PROJECT_NAME}::nghttp2 ALIAS ${LIB_SELECTED}) ++add_library(nghttp2 ALIAS ${LIB_SELECTED}) + + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +- +-install(EXPORT ${EXPORT_SET} +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} +- NAMESPACE ${PROJECT_NAME}::) +diff --git a/deps/nghttp2/lib/Makefile.am b/deps/nghttp2/lib/Makefile.am +index 1168c1e6..3a743df6 100644 +--- a/deps/nghttp2/lib/Makefile.am ++++ b/deps/nghttp2/lib/Makefile.am +@@ -22,7 +22,7 @@ + # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + SUBDIRS = includes + +-EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in ++EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in + + AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG) + AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \ +diff --git a/deps/nghttp2/lib/Makefile.in b/deps/nghttp2/lib/Makefile.in +index 14686ef1..bb458a18 100644 +--- a/deps/nghttp2/lib/Makefile.in ++++ b/deps/nghttp2/lib/Makefile.in +@@ -360,6 +360,10 @@ LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@ + LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@ + LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ + LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ ++LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS = @LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS@ ++LIBNGTCP2_CRYPTO_LIBRESSL_LIBS = @LIBNGTCP2_CRYPTO_LIBRESSL_LIBS@ ++LIBNGTCP2_CRYPTO_OSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OSSL_CFLAGS@ ++LIBNGTCP2_CRYPTO_OSSL_LIBS = @LIBNGTCP2_CRYPTO_OSSL_LIBS@ + LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS = @LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@ + LIBNGTCP2_CRYPTO_QUICTLS_LIBS = @LIBNGTCP2_CRYPTO_QUICTLS_LIBS@ + LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS = @LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@ +@@ -492,7 +496,7 @@ top_srcdir = @top_srcdir@ + # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + SUBDIRS = includes +-EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in ++EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in + AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG) + AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \ + @DEFS@ +diff --git a/deps/nghttp2/lib/config.cmake.in b/deps/nghttp2/lib/config.cmake.in +new file mode 100644 +index 00000000..0b677718 +--- /dev/null ++++ b/deps/nghttp2/lib/config.cmake.in +@@ -0,0 +1,3 @@ ++include(CMakeFindDependencyMacro) ++ ++include("${CMAKE_CURRENT_LIST_DIR}/@NGHTTP2_TARGETS_EXPORT_NAME@.cmake") +diff --git a/deps/nghttp2/lib/includes/Makefile.in b/deps/nghttp2/lib/includes/Makefile.in +index 778dcb87..a4687390 100644 +--- a/deps/nghttp2/lib/includes/Makefile.in ++++ b/deps/nghttp2/lib/includes/Makefile.in +@@ -265,6 +265,10 @@ LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@ + LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@ + LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ + LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ ++LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS = @LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS@ ++LIBNGTCP2_CRYPTO_LIBRESSL_LIBS = @LIBNGTCP2_CRYPTO_LIBRESSL_LIBS@ ++LIBNGTCP2_CRYPTO_OSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OSSL_CFLAGS@ ++LIBNGTCP2_CRYPTO_OSSL_LIBS = @LIBNGTCP2_CRYPTO_OSSL_LIBS@ + LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS = @LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@ + LIBNGTCP2_CRYPTO_QUICTLS_LIBS = @LIBNGTCP2_CRYPTO_QUICTLS_LIBS@ + LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS = @LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@ +diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h +index 2ef49b8d..19c1874f 100644 +--- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h ++++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h +@@ -2039,18 +2039,19 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session, + /** + * @functypedef + * +- * Callback function invoked when a invalid header name/value pair is ++ * Callback function invoked when an invalid header name/value pair is + * received for the |frame|. + * + * The parameter and behaviour are similar to + * :type:`nghttp2_on_header_callback`. The difference is that this +- * callback is only invoked when a invalid header name/value pair is +- * received which is treated as stream error if this callback is not +- * set. Only invalid regular header field are passed to this +- * callback. In other words, invalid pseudo header field is not +- * passed to this callback. Also header fields which includes upper +- * cased latter are also treated as error without passing them to this +- * callback. ++ * callback is only invoked when an invalid header name/value pair is ++ * received which is treated as stream error if this callback returns ++ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and ++ * :type:`nghttp2_on_invalid_header_callback2` is not set. Only ++ * invalid regular header field are passed to this callback. In other ++ * words, invalid pseudo header field is not passed to this callback. ++ * Also header fields which includes upper cased latter are also ++ * treated as error without passing them to this callback. + * + * This callback is only considered if HTTP messaging validation is + * turned on (which is on by default, see +@@ -2076,17 +2077,18 @@ typedef int (*nghttp2_on_invalid_header_callback)( + /** + * @functypedef + * +- * Callback function invoked when a invalid header name/value pair is ++ * Callback function invoked when an invalid header name/value pair is + * received for the |frame|. + * + * The parameter and behaviour are similar to + * :type:`nghttp2_on_header_callback2`. The difference is that this +- * callback is only invoked when a invalid header name/value pair is +- * received which is silently ignored if this callback is not set. +- * Only invalid regular header field are passed to this callback. In +- * other words, invalid pseudo header field is not passed to this +- * callback. Also header fields which includes upper cased latter are +- * also treated as error without passing them to this callback. ++ * callback is only invoked when an invalid header name/value pair is ++ * received which is silently ignored if neither this callback nor ++ * :type:`nghttp2_on_invalid_header_callback` is set. Only invalid ++ * regular header field are passed to this callback. In other words, ++ * invalid pseudo header field is not passed to this callback. Also ++ * header fields which includes upper cased latter are also treated as ++ * error without passing them to this callback. + * + * This callback is only considered if HTTP messaging validation is + * turned on (which is on by default, see +@@ -2445,6 +2447,15 @@ typedef int (*nghttp2_error_callback2)(nghttp2_session *session, + int lib_error_code, const char *msg, + size_t len, void *user_data); + ++/** ++ * @functypedef ++ * ++ * Callback function invoked when unpredictable data of |destlen| ++ * bytes are needed. The implementation must write unpredictable data ++ * of |destlen| bytes into the buffer pointed by |dest|. ++ */ ++typedef void (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen); ++ + struct nghttp2_session_callbacks; + + /** +@@ -2649,7 +2660,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2( + /** + * @function + * +- * Sets callback function invoked when a invalid header name/value ++ * Sets callback function invoked when an invalid header name/value + * pair is received. If both + * `nghttp2_session_callbacks_set_on_invalid_header_callback()` and + * `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are +@@ -2662,7 +2673,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback( + /** + * @function + * +- * Sets callback function invoked when a invalid header name/value ++ * Sets callback function invoked when an invalid header name/value + * pair is received. + */ + NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2( +@@ -2833,6 +2844,18 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( + NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2( + nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2); + ++/** ++ * @function ++ * ++ * Sets callback function invoked when unpredictable data is needed. ++ * Although this callback is optional due to the backward ++ * compatibility, it is recommended to specify it to harden the ++ * runtime behavior against suspicious activities of a remote ++ * endpoint. ++ */ ++NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback( ++ nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback); ++ + /** + * @functypedef + * +@@ -3133,14 +3156,12 @@ nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option, + /** + * @function + * +- * This option prevents the library from retaining closed streams to +- * maintain the priority tree. If this option is set to nonzero, +- * applications can discard closed stream completely to save memory. ++ * .. warning:: + * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is submitted via `nghttp2_submit_settings()`, any +- * closed streams are not retained regardless of this option. ++ * Deprecated. Closed streams are not retained anymore. ++ * ++ * This function works as before, but it does not take any effect ++ * against :type:`nghttp2_session`. + */ + NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option, + int val); +@@ -3170,16 +3191,11 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option, + /** + * @function + * +- * This option, if set to nonzero, allows server to fallback to +- * :rfc:`7540` priorities if SETTINGS_NO_RFC7540_PRIORITIES was not +- * received from client, and server submitted +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * = 1 via `nghttp2_submit_settings()`. Most of the advanced +- * functionality for RFC 7540 priorities are still disabled. This +- * fallback only enables the minimal feature set of RFC 7540 +- * priorities to deal with priority signaling from client. ++ * .. warning:: ++ * Deprecated. :rfc:`7540` priorities have been removed. + * +- * Client session ignores this option. ++ * This function works as before, but it does not take any effect ++ * against :type:`nghttp2_session`. + */ + NGHTTP2_EXTERN void + nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option, +@@ -3225,6 +3241,23 @@ nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, + NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option, + size_t val); + ++/** ++ * @function ++ * ++ * This function sets the rate limit for the "glitches", the ++ * suspicious activities from a remote endpoint. It is a token-bucket ++ * based rate limiter. |burst| specifies the number of tokens that is ++ * initially available. The maximum number of tokens is capped to ++ * this value. |rate| specifies the number of tokens that are ++ * regenerated per second. When a suspicious activity is detected, ++ * some amount of tokens are consumed. If there is no token ++ * available, GOAWAY is sent to tear down the connection. |burst| and ++ * |rate| default to 1000 and 33 respectively. ++ */ ++NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option, ++ uint64_t burst, ++ uint64_t rate); ++ + /** + * @function + * +@@ -4179,39 +4212,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session, + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return 0 without doing anything. +- * +- * Changes priority of existing stream denoted by |stream_id|. The +- * new priority specification is |pri_spec|. +- * +- * The priority is changed silently and instantly, and no PRIORITY +- * frame will be sent to notify the peer of this change. This +- * function may be useful for server to change the priority of pushed +- * stream. +- * +- * If |session| is initialized as server, and ``pri_spec->stream_id`` +- * points to the idle stream, the idle stream is created if it does +- * not exist. The created idle stream will depend on root stream +- * (stream 0) with weight 16. +- * +- * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not +- * found, we use default priority instead of given |pri_spec|. That +- * is make stream depend on root stream with weight 16. +- * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is submitted via `nghttp2_submit_settings()`, this +- * function does nothing and returns 0. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: ++ * prioritization scheme. + * +- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` +- * Out of memory. +- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` +- * Attempted to depend on itself; or no stream exist for the given +- * |stream_id|; or |stream_id| is 0 ++ * This function is noop. It always returns 0. + */ + NGHTTP2_EXTERN int + nghttp2_session_change_stream_priority(nghttp2_session *session, +@@ -4225,51 +4228,9 @@ nghttp2_session_change_stream_priority(nghttp2_session *session, + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return 0 without doing anything. +- * +- * Creates idle stream with the given |stream_id|, and priority +- * |pri_spec|. +- * +- * The stream creation is done without sending PRIORITY frame, which +- * means that peer does not know about the existence of this idle +- * stream in the local endpoint. +- * +- * RFC 7540 does not disallow the use of creation of idle stream with +- * odd or even stream ID regardless of client or server. So this +- * function can create odd or even stream ID regardless of client or +- * server. But probably it is a bit safer to use the stream ID the +- * local endpoint can initiate (in other words, use odd stream ID for +- * client, and even stream ID for server), to avoid potential +- * collision from peer's instruction. Also we can use +- * `nghttp2_session_set_next_stream_id()` to avoid to open created +- * idle streams accidentally if we follow this recommendation. +- * +- * If |session| is initialized as server, and ``pri_spec->stream_id`` +- * points to the idle stream, the idle stream is created if it does +- * not exist. The created idle stream will depend on root stream +- * (stream 0) with weight 16. +- * +- * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not +- * found, we use default priority instead of given |pri_spec|. That +- * is make stream depend on root stream with weight 16. +- * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is submitted via `nghttp2_submit_settings()`, this +- * function does nothing and returns 0. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: ++ * prioritization scheme. + * +- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` +- * Out of memory. +- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` +- * Attempted to depend on itself; or stream denoted by |stream_id| +- * already exists; or |stream_id| cannot be used to create idle +- * stream (in other words, local endpoint has already opened +- * stream ID greater than or equal to the given stream ID; or +- * |stream_id| is 0 ++ * This function is noop. It always returns 0. + */ + NGHTTP2_EXTERN int + nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id, +@@ -4505,23 +4466,7 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); + * + * Submits HEADERS frame and optionally one or more DATA frames. + * +- * The |pri_spec| is a deprecated priority specification of this +- * request. ``NULL`` means the default priority (see +- * `nghttp2_priority_spec_default_init()`). To specify the priority, +- * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, +- * this function will copy its data members. +- * +- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, +- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` +- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than +- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MAX_WEIGHT`. +- * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is received by a remote endpoint, |pri_spec| is +- * ignored, and treated as if ``NULL`` is specified. ++ * The |pri_spec| is ignored. + * + * The |nva| is an array of name/value pair :type:`nghttp2_nv` with + * |nvlen| elements. The application is responsible to include +@@ -4564,9 +4509,6 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` + * No stream ID is available because maximum stream ID was + * reached. +- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` +- * Trying to depend on itself (new stream ID equals +- * ``pri_spec->stream_id``). + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` + * The |session| is server session. + * +@@ -4594,25 +4536,7 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request( + * + * Submits HEADERS frame and optionally one or more DATA frames. + * +- * The |pri_spec| is a deprecated priority specification of this +- * request. ``NULL`` means the default priority (see +- * `nghttp2_priority_spec_default_init()`). To specify the priority, +- * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, +- * this function will copy its data members. In the future release +- * after the end of 2024, this function will ignore |pri_spec| and +- * behave as if ``NULL`` is given. +- * +- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, +- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` +- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than +- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MAX_WEIGHT`. +- * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is received by a remote endpoint, |pri_spec| is +- * ignored, and treated as if ``NULL`` is specified. ++ * The |pri_spec| is ignored. + * + * The |nva| is an array of name/value pair :type:`nghttp2_nv` with + * |nvlen| elements. The application is responsible to include +@@ -4655,9 +4579,6 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request( + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` + * No stream ID is available because maximum stream ID was + * reached. +- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` +- * Trying to depend on itself (new stream ID equals +- * ``pri_spec->stream_id``). + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` + * The |session| is server session. + * +@@ -4899,24 +4820,7 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, + * assigned stream ID will be returned. Otherwise, specify stream ID + * in |stream_id|. + * +- * The |pri_spec| is a deprecated priority specification of this +- * request. ``NULL`` means the default priority (see +- * `nghttp2_priority_spec_default_init()`). To specify the priority, +- * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, +- * this function will copy its data members. In the future release +- * after the end of 2024, this function will ignore |pri_spec| and +- * behave as if ``NULL`` is given. +- * +- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, +- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` +- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than +- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`. +- * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is received by a remote endpoint, |pri_spec| is +- * ignored, and treated as if ``NULL`` is specified. ++ * The |pri_spec| is ignored. + * + * The |nva| is an array of name/value pair :type:`nghttp2_nv` with + * |nvlen| elements. The application is responsible to include +@@ -4956,8 +4860,7 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, + * No stream ID is available because maximum stream ID was + * reached. + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` +- * The |stream_id| is 0; or trying to depend on itself (stream ID +- * equals ``pri_spec->stream_id``). ++ * The |stream_id| is 0. + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` + * DATA or HEADERS has been already submitted and not fully + * processed yet. This happens if stream denoted by |stream_id| +@@ -5083,40 +4986,9 @@ NGHTTP2_EXTERN int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return 0 without doing anything. +- * +- * Submits PRIORITY frame to change the priority of stream |stream_id| +- * to the priority specification |pri_spec|. +- * +- * The |flags| is currently ignored and should be +- * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. +- * +- * The |pri_spec| is a deprecated priority specification of this +- * request. ``NULL`` is not allowed for this function. To specify the +- * priority, use `nghttp2_priority_spec_init()`. This function will +- * copy its data members. +- * +- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, +- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` +- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than +- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes +- * :macro:`NGHTTP2_MAX_WEIGHT`. +- * +- * If +- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` +- * of value of 1 is received by a remote endpoint, this function does +- * nothing and returns 0. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: ++ * prioritization scheme. + * +- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` +- * Out of memory. +- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` +- * The |stream_id| is 0; or the |pri_spec| is NULL; or trying to +- * depend on itself. ++ * This function is noop. It always returns 0. + */ + NGHTTP2_EXTERN int + nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, +@@ -6885,11 +6757,9 @@ nghttp2_session_get_root_stream(nghttp2_session *session); + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return NULL. ++ * prioritization scheme. + * +- * Returns the parent stream of |stream| in dependency tree. Returns +- * NULL if there is no such stream. ++ * This function always returns NULL. + */ + NGHTTP2_EXTERN nghttp2_stream * + nghttp2_stream_get_parent(nghttp2_stream *stream); +@@ -6903,11 +6773,9 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream); + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return NULL. ++ * prioritization scheme. + * +- * Returns the next sibling stream of |stream| in dependency tree. +- * Returns NULL if there is no such stream. ++ * This function always returns NULL. + */ + NGHTTP2_EXTERN nghttp2_stream * + nghttp2_stream_get_next_sibling(nghttp2_stream *stream); +@@ -6919,11 +6787,9 @@ nghttp2_stream_get_next_sibling(nghttp2_stream *stream); + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return NULL. ++ * prioritization scheme. + * +- * Returns the previous sibling stream of |stream| in dependency tree. +- * Returns NULL if there is no such stream. ++ * This function always returns NULL. + */ + NGHTTP2_EXTERN nghttp2_stream * + nghttp2_stream_get_previous_sibling(nghttp2_stream *stream); +@@ -6935,11 +6801,9 @@ nghttp2_stream_get_previous_sibling(nghttp2_stream *stream); + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return NULL. ++ * prioritization scheme. + * +- * Returns the first child stream of |stream| in dependency tree. +- * Returns NULL if there is no such stream. ++ * This function always returns NULL. + */ + NGHTTP2_EXTERN nghttp2_stream * + nghttp2_stream_get_first_child(nghttp2_stream *stream); +@@ -6951,11 +6815,9 @@ nghttp2_stream_get_first_child(nghttp2_stream *stream); + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return +- * :macro:`NGHTTP2_DEFAULT_WEIGHT`. ++ * prioritization scheme. + * +- * Returns dependency weight to the parent stream of |stream|. ++ * This function always returns :macro:`NGHTTP2_DEFAULT_WEIGHT`. + */ + NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream); + +@@ -6966,10 +6828,9 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream); + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible +- * prioritization scheme. In the future release after the end of +- * 2024, this function will always return 0. ++ * prioritization scheme. + * +- * Returns the sum of the weight for |stream|'s children. ++ * This function always returns 0. + */ + NGHTTP2_EXTERN int32_t + nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream); +diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h +index 827c9989..95acef22 100644 +--- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h ++++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h +@@ -29,7 +29,7 @@ + * @macro + * Version number of the nghttp2 library release + */ +-#define NGHTTP2_VERSION "1.64.0" ++#define NGHTTP2_VERSION "1.68.1" + + /** + * @macro +@@ -37,6 +37,6 @@ + * release. This is a 24 bit number with 8 bits for major number, 8 bits + * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. + */ +-#define NGHTTP2_VERSION_NUM 0x014000 ++#define NGHTTP2_VERSION_NUM 0x014401 + + #endif /* NGHTTP2VER_H */ +diff --git a/deps/nghttp2/lib/nghttp2_alpn.h b/deps/nghttp2/lib/nghttp2_alpn.h +index 09810fd8..ecc9ed20 100644 +--- a/deps/nghttp2/lib/nghttp2_alpn.h ++++ b/deps/nghttp2/lib/nghttp2_alpn.h +@@ -27,8 +27,8 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +-#endif /* NGHTTP2_ALPN_H */ ++#endif /* !defined(NGHTTP2_ALPN_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_buf.h b/deps/nghttp2/lib/nghttp2_buf.h +index 95ff3706..636aa619 100644 +--- a/deps/nghttp2/lib/nghttp2_buf.h ++++ b/deps/nghttp2/lib/nghttp2_buf.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -409,4 +409,4 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs); + */ + size_t nghttp2_bufs_len(nghttp2_bufs *bufs); + +-#endif /* NGHTTP2_BUF_H */ ++#endif /* !defined(NGHTTP2_BUF_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_callbacks.c b/deps/nghttp2/lib/nghttp2_callbacks.c +index 32fedd52..162ca6bd 100644 +--- a/deps/nghttp2/lib/nghttp2_callbacks.c ++++ b/deps/nghttp2/lib/nghttp2_callbacks.c +@@ -201,3 +201,8 @@ void nghttp2_session_callbacks_set_error_callback2( + nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) { + cbs->error_callback2 = error_callback2; + } ++ ++void nghttp2_session_callbacks_set_rand_callback( ++ nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) { ++ cbs->rand_callback = rand_callback; ++} +diff --git a/deps/nghttp2/lib/nghttp2_callbacks.h b/deps/nghttp2/lib/nghttp2_callbacks.h +index a611f485..4b45e578 100644 +--- a/deps/nghttp2/lib/nghttp2_callbacks.h ++++ b/deps/nghttp2/lib/nghttp2_callbacks.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -151,6 +151,7 @@ struct nghttp2_session_callbacks { + nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback; + nghttp2_error_callback error_callback; + nghttp2_error_callback2 error_callback2; ++ nghttp2_rand_callback rand_callback; + }; + +-#endif /* NGHTTP2_CALLBACKS_H */ ++#endif /* !defined(NGHTTP2_CALLBACKS_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_debug.c b/deps/nghttp2/lib/nghttp2_debug.c +index 09dd2b28..b5f33ef3 100644 +--- a/deps/nghttp2/lib/nghttp2_debug.c ++++ b/deps/nghttp2/lib/nghttp2_debug.c +@@ -50,11 +50,11 @@ void nghttp2_set_debug_vprintf_callback( + static_debug_vprintf_callback = debug_vprintf_callback; + } + +-#else /* !DEBUGBUILD */ ++#else /* !defined(DEBUGBUILD) */ + + void nghttp2_set_debug_vprintf_callback( + nghttp2_debug_vprintf_callback debug_vprintf_callback) { + (void)debug_vprintf_callback; + } + +-#endif /* !DEBUGBUILD */ ++#endif /* !defined(DEBUGBUILD) */ +diff --git a/deps/nghttp2/lib/nghttp2_debug.h b/deps/nghttp2/lib/nghttp2_debug.h +index cbb4dd57..26566a62 100644 +--- a/deps/nghttp2/lib/nghttp2_debug.h ++++ b/deps/nghttp2/lib/nghttp2_debug.h +@@ -27,17 +27,17 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + + #ifdef DEBUGBUILD + # define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__) + void nghttp2_debug_vprintf(const char *format, ...); +-#else ++#else /* !defined(DEBUGBUILD) */ + # define DEBUGF(...) \ + do { \ + } while (0) +-#endif ++#endif /* !defined(DEBUGBUILD) */ + +-#endif /* NGHTTP2_DEBUG_H */ ++#endif /* !defined(NGHTTP2_DEBUG_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_extpri.h b/deps/nghttp2/lib/nghttp2_extpri.h +index db911972..2e039165 100644 +--- a/deps/nghttp2/lib/nghttp2_extpri.h ++++ b/deps/nghttp2/lib/nghttp2_extpri.h +@@ -28,7 +28,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -62,4 +62,4 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri); + */ + #define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0) + +-#endif /* NGHTTP2_EXTPRI_H */ ++#endif /* !defined(NGHTTP2_EXTPRI_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_frame.c b/deps/nghttp2/lib/nghttp2_frame.c +index edc2aaaa..264ae9d3 100644 +--- a/deps/nghttp2/lib/nghttp2_frame.c ++++ b/deps/nghttp2/lib/nghttp2_frame.c +@@ -750,6 +750,16 @@ void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, + uint8_t *p; + + altsvc = frame->payload; ++ ++ if (payloadlen == 0) { ++ altsvc->origin = NULL; ++ altsvc->origin_len = 0; ++ altsvc->field_value = NULL; ++ altsvc->field_value_len = 0; ++ ++ return; ++ } ++ + p = payload; + + altsvc->origin = p; +diff --git a/deps/nghttp2/lib/nghttp2_frame.h b/deps/nghttp2/lib/nghttp2_frame.h +index d5866880..ed4ab2c6 100644 +--- a/deps/nghttp2/lib/nghttp2_frame.h ++++ b/deps/nghttp2/lib/nghttp2_frame.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include "nghttp2_hd.h" +@@ -634,4 +634,4 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv); + void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, + size_t padlen, int framehd_only); + +-#endif /* NGHTTP2_FRAME_H */ ++#endif /* !defined(NGHTTP2_FRAME_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_hd.c b/deps/nghttp2/lib/nghttp2_hd.c +index 55fc2cc6..ad85eed1 100644 +--- a/deps/nghttp2/lib/nghttp2_hd.c ++++ b/deps/nghttp2/lib/nghttp2_hd.c +@@ -594,8 +594,19 @@ static void hd_map_remove(nghttp2_hd_map *map, nghttp2_hd_entry *ent) { + static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize, + nghttp2_mem *mem) { + size_t size; ++ const size_t max_size = SIZE_MAX / sizeof(nghttp2_hd_entry *); ++ ++ if (bufsize > max_size) { ++ return NGHTTP2_ERR_NOMEM; ++ } ++ + for (size = 1; size < bufsize; size <<= 1) + ; ++ ++ if (size > max_size) { ++ return NGHTTP2_ERR_NOMEM; ++ } ++ + ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size); + if (ringbuf->buffer == NULL) { + return NGHTTP2_ERR_NOMEM; +diff --git a/deps/nghttp2/lib/nghttp2_hd.h b/deps/nghttp2/lib/nghttp2_hd.h +index 38a31a83..bdc7fad5 100644 +--- a/deps/nghttp2/lib/nghttp2_hd.h ++++ b/deps/nghttp2/lib/nghttp2_hd.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -439,4 +439,4 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, + */ + int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx); + +-#endif /* NGHTTP2_HD_H */ ++#endif /* !defined(NGHTTP2_HD_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.h b/deps/nghttp2/lib/nghttp2_hd_huffman.h +index 2bfd5318..df037a8b 100644 +--- a/deps/nghttp2/lib/nghttp2_hd_huffman.h ++++ b/deps/nghttp2/lib/nghttp2_hd_huffman.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -69,4 +69,4 @@ typedef struct { + extern const nghttp2_huff_sym huff_sym_table[]; + extern const nghttp2_huff_decode huff_decode_table[][16]; + +-#endif /* NGHTTP2_HD_HUFFMAN_H */ ++#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_helper.h b/deps/nghttp2/lib/nghttp2_helper.h +index f5de6290..7d640761 100644 +--- a/deps/nghttp2/lib/nghttp2_helper.h ++++ b/deps/nghttp2/lib/nghttp2_helper.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include +@@ -142,4 +142,4 @@ int nghttp2_should_send_window_update(int32_t local_window_size, + */ + uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len); + +-#endif /* NGHTTP2_HELPER_H */ ++#endif /* !defined(NGHTTP2_HELPER_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_http.c b/deps/nghttp2/lib/nghttp2_http.c +index f222fe5e..60a0b01e 100644 +--- a/deps/nghttp2/lib/nghttp2_http.c ++++ b/deps/nghttp2/lib/nghttp2_http.c +@@ -207,7 +207,6 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv, + if (!trailer && + /* Do not parse the header field in PUSH_PROMISE. */ + (stream->stream_id & 1) && +- (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) && + !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) { + nghttp2_extpri_from_uint8(&extpri, stream->http_extpri); + if (nghttp2_http_parse_priority(&extpri, nv->value->base, +@@ -660,17 +659,17 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream, + int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, + size_t valuelen) { + nghttp2_extpri 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; + } + +@@ -683,7 +682,7 @@ int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, + + switch (key.base[0]) { + case 'i': +- if (val.type != SF_TYPE_BOOLEAN) { ++ if (val.type != SFPARSE_TYPE_BOOLEAN) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + +@@ -691,7 +690,7 @@ int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, + + break; + case 'u': +- if (val.type != SF_TYPE_INTEGER || ++ if (val.type != SFPARSE_TYPE_INTEGER || + val.integer < NGHTTP2_EXTPRI_URGENCY_HIGH || + NGHTTP2_EXTPRI_URGENCY_LOW < val.integer) { + return NGHTTP2_ERR_INVALID_ARGUMENT; +diff --git a/deps/nghttp2/lib/nghttp2_http.h b/deps/nghttp2/lib/nghttp2_http.h +index d9992fe6..2925334c 100644 +--- a/deps/nghttp2/lib/nghttp2_http.h ++++ b/deps/nghttp2/lib/nghttp2_http.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include "nghttp2_session.h" +@@ -97,4 +97,4 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream, + int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, + size_t valuelen); + +-#endif /* NGHTTP2_HTTP_H */ ++#endif /* !defined(NGHTTP2_HTTP_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_int.h b/deps/nghttp2/lib/nghttp2_int.h +index b23585cc..d89cf154 100644 +--- a/deps/nghttp2/lib/nghttp2_int.h ++++ b/deps/nghttp2/lib/nghttp2_int.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -52,7 +52,11 @@ typedef enum { + * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke + * nghttp2_on_invalid_header_callback. + */ +- NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106 ++ NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106, ++ /* ++ * Cancel pushed stream. ++ */ ++ NGHTTP2_ERR_PUSH_CANCEL = -107, + } nghttp2_internal_error; + +-#endif /* NGHTTP2_INT_H */ ++#endif /* !defined(NGHTTP2_INT_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_map.c b/deps/nghttp2/lib/nghttp2_map.c +index ee6bb196..f89f3103 100644 +--- a/deps/nghttp2/lib/nghttp2_map.c ++++ b/deps/nghttp2/lib/nghttp2_map.c +@@ -31,12 +31,13 @@ + + #include "nghttp2_helper.h" + +-#define NGHTTP2_INITIAL_TABLE_LENBITS 4 ++#define NGHTTP2_INITIAL_HASHBITS 4 + +-void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) { ++void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem) { + map->mem = mem; + map->hashbits = 0; + map->table = NULL; ++ map->seed = seed; + map->size = 0; + } + +@@ -77,8 +78,13 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), + return 0; + } + +-static size_t hash(nghttp2_map_key_type key, size_t bits) { +- return (size_t)(((uint32_t)key * 2654435769u) >> (32 - bits)); ++static size_t map_hash(const nghttp2_map *map, nghttp2_map_key_type key) { ++ /* hasher from ++ https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs ++ We do not perform finalization here because we use top bits ++ anyway. */ ++ uint32_t h = ((uint32_t)key + map->seed) * 0x93d765dd; ++ return (size_t)((h * 2654435769u) >> (32 - map->hashbits)); + } + + static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) { +@@ -109,24 +115,28 @@ void nghttp2_map_print_distance(const nghttp2_map *map) { + continue; + } + +- idx = hash(bkt->key, map->hashbits); ++ idx = map_hash(map, bkt->key); + fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i, +- hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl); ++ map_hash(map, bkt->key), bkt->key, idx, bkt->psl); + } + } +-#endif /* !WIN32 */ +- +-static int insert(nghttp2_map_bucket *table, size_t hashbits, +- nghttp2_map_key_type key, void *data) { +- size_t idx = hash(key, hashbits); +- nghttp2_map_bucket b = {0, key, data}, *bkt; +- size_t mask = (1u << hashbits) - 1; ++#endif /* !defined(WIN32) */ ++ ++static int map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { ++ size_t idx = map_hash(map, key); ++ nghttp2_map_bucket b = { ++ .key = key, ++ .data = data, ++ }; ++ nghttp2_map_bucket *bkt; ++ size_t mask = (1u << map->hashbits) - 1; + + for (;;) { +- bkt = &table[idx]; ++ bkt = &map->table[idx]; + + if (bkt->data == NULL) { + *bkt = b; ++ ++map->size; + return 0; + } + +@@ -147,15 +157,19 @@ static int insert(nghttp2_map_bucket *table, size_t hashbits, + + static int map_resize(nghttp2_map *map, size_t new_hashbits) { + size_t i; +- nghttp2_map_bucket *new_table; + nghttp2_map_bucket *bkt; + size_t tablelen; + int rv; ++ nghttp2_map new_map = { ++ .table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits, ++ sizeof(nghttp2_map_bucket)), ++ .mem = map->mem, ++ .seed = map->seed, ++ .hashbits = new_hashbits, ++ }; + (void)rv; + +- new_table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits, +- sizeof(nghttp2_map_bucket)); +- if (new_table == NULL) { ++ if (new_map.table == NULL) { + return NGHTTP2_ERR_NOMEM; + } + +@@ -168,15 +182,15 @@ static int map_resize(nghttp2_map *map, size_t new_hashbits) { + continue; + } + +- rv = insert(new_table, new_hashbits, bkt->key, bkt->data); ++ rv = map_insert(&new_map, bkt->key, bkt->data); + + assert(0 == rv); + } + } + + nghttp2_mem_free(map->mem, map->table); ++ map->table = new_map.table; + map->hashbits = new_hashbits; +- map->table = new_table; + + return 0; + } +@@ -186,30 +200,28 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { + + assert(data); + +- /* Load factor is 0.75 */ ++ /* Load factor is 7/8 */ + /* Under the very initial condition, that is map->size == 0 and +- map->hashbits == 0, 4 > 3 still holds nicely. */ +- if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) { ++ map->hashbits == 0, 8 > 7 still holds nicely. */ ++ if ((map->size + 1) * 8 > (1u << map->hashbits) * 7) { + if (map->hashbits) { + rv = map_resize(map, map->hashbits + 1); + if (rv != 0) { + return rv; + } + } else { +- rv = map_resize(map, NGHTTP2_INITIAL_TABLE_LENBITS); ++ rv = map_resize(map, NGHTTP2_INITIAL_HASHBITS); + if (rv != 0) { + return rv; + } + } + } + +- rv = insert(map->table, map->hashbits, key, data); ++ rv = map_insert(map, key, data); + if (rv != 0) { + return rv; + } + +- ++map->size; +- + return 0; + } + +@@ -223,7 +235,7 @@ void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) { + return NULL; + } + +- idx = hash(key, map->hashbits); ++ idx = map_hash(map, key); + mask = (1u << map->hashbits) - 1; + + for (;;) { +@@ -252,7 +264,7 @@ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + +- idx = hash(key, map->hashbits); ++ idx = map_hash(map, key); + mask = (1u << map->hashbits) - 1; + + for (;;) { +diff --git a/deps/nghttp2/lib/nghttp2_map.h b/deps/nghttp2/lib/nghttp2_map.h +index 5adfb78d..e45685bc 100644 +--- a/deps/nghttp2/lib/nghttp2_map.h ++++ b/deps/nghttp2/lib/nghttp2_map.h +@@ -28,7 +28,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -47,6 +47,7 @@ typedef struct nghttp2_map_bucket { + typedef struct nghttp2_map { + nghttp2_map_bucket *table; + nghttp2_mem *mem; ++ uint32_t seed; + size_t size; + size_t hashbits; + } nghttp2_map; +@@ -54,7 +55,7 @@ typedef struct nghttp2_map { + /* + * nghttp2_map_init initializes the map |map|. + */ +-void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem); ++void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem); + + /* + * nghttp2_map_free deallocates any resources allocated for |map|. +@@ -123,6 +124,6 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), + + #ifndef WIN32 + void nghttp2_map_print_distance(const nghttp2_map *map); +-#endif /* !WIN32 */ ++#endif /* !defined(WIN32) */ + +-#endif /* NGHTTP2_MAP_H */ ++#endif /* !defined(NGHTTP2_MAP_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_mem.h b/deps/nghttp2/lib/nghttp2_mem.h +index f83dbcb8..10af7c69 100644 +--- a/deps/nghttp2/lib/nghttp2_mem.h ++++ b/deps/nghttp2/lib/nghttp2_mem.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -42,4 +42,4 @@ void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data); + void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size); + void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size); + +-#endif /* NGHTTP2_MEM_H */ ++#endif /* !defined(NGHTTP2_MEM_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_net.h b/deps/nghttp2/lib/nghttp2_net.h +index 521f9814..0c57d947 100644 +--- a/deps/nghttp2/lib/nghttp2_net.h ++++ b/deps/nghttp2/lib/nghttp2_net.h +@@ -27,28 +27,28 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #ifdef HAVE_ARPA_INET_H + # include +-#endif /* HAVE_ARPA_INET_H */ ++#endif /* defined(HAVE_ARPA_INET_H) */ + + #ifdef HAVE_NETINET_IN_H + # include +-#endif /* HAVE_NETINET_IN_H */ ++#endif /* defined(HAVE_NETINET_IN_H) */ + + #include + +-#if defined(WIN32) ++#ifdef WIN32 + /* Windows requires ws2_32 library for ntonl family functions. We + define inline functions for those function so that we don't have + dependency on that lib. */ + + # ifdef _MSC_VER + # define STIN static __inline +-# else ++# else /* !defined(_MSC_VER) */ + # define STIN static inline +-# endif ++# endif /* !defined(_MSC_VER) */ + + STIN uint32_t htonl(uint32_t hostlong) { + uint32_t res; +@@ -86,6 +86,6 @@ STIN uint16_t ntohs(uint16_t netshort) { + return res; + } + +-#endif /* WIN32 */ ++#endif /* defined(WIN32) */ + +-#endif /* NGHTTP2_NET_H */ ++#endif /* !defined(NGHTTP2_NET_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_option.c b/deps/nghttp2/lib/nghttp2_option.c +index 02a24eee..7e44a241 100644 +--- a/deps/nghttp2/lib/nghttp2_option.c ++++ b/deps/nghttp2/lib/nghttp2_option.c +@@ -155,3 +155,10 @@ void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) { + option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS; + option->max_continuations = val; + } ++ ++void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option, ++ uint64_t burst, uint64_t rate) { ++ option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT; ++ option->glitch_burst = burst; ++ option->glitch_rate = rate; ++} +diff --git a/deps/nghttp2/lib/nghttp2_option.h b/deps/nghttp2/lib/nghttp2_option.h +index c89cb97f..711185ba 100644 +--- a/deps/nghttp2/lib/nghttp2_option.h ++++ b/deps/nghttp2/lib/nghttp2_option.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -72,6 +72,7 @@ typedef enum { + NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14, + NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15, + NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16, ++ NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17, + } nghttp2_option_flag; + + /** +@@ -83,6 +84,11 @@ struct nghttp2_option { + */ + uint64_t stream_reset_burst; + uint64_t stream_reset_rate; ++ /** ++ * NGHTTP2_OPT_GLITCH_RATE_LIMIT ++ */ ++ uint64_t glitch_burst; ++ uint64_t glitch_rate; + /** + * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH + */ +@@ -154,4 +160,4 @@ struct nghttp2_option { + uint8_t user_recv_ext_types[32]; + }; + +-#endif /* NGHTTP2_OPTION_H */ ++#endif /* !defined(NGHTTP2_OPTION_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_outbound_item.h b/deps/nghttp2/lib/nghttp2_outbound_item.h +index 4e917500..6e8e310c 100644 +--- a/deps/nghttp2/lib/nghttp2_outbound_item.h ++++ b/deps/nghttp2/lib/nghttp2_outbound_item.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include "nghttp2_frame.h" +@@ -186,4 +186,4 @@ void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q); + /* Returns the size of the queue */ + #define nghttp2_outbound_queue_size(Q) ((Q)->n) + +-#endif /* NGHTTP2_OUTBOUND_ITEM_H */ ++#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_pq.h b/deps/nghttp2/lib/nghttp2_pq.h +index c8d90ef2..5dd863f8 100644 +--- a/deps/nghttp2/lib/nghttp2_pq.h ++++ b/deps/nghttp2/lib/nghttp2_pq.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include "nghttp2_int.h" +@@ -121,4 +121,4 @@ int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg); + */ + void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item); + +-#endif /* NGHTTP2_PQ_H */ ++#endif /* !defined(NGHTTP2_PQ_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_priority_spec.h b/deps/nghttp2/lib/nghttp2_priority_spec.h +index 92ece822..158e0dcd 100644 +--- a/deps/nghttp2/lib/nghttp2_priority_spec.h ++++ b/deps/nghttp2/lib/nghttp2_priority_spec.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -39,4 +39,4 @@ + */ + void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec); + +-#endif /* NGHTTP2_PRIORITY_SPEC_H */ ++#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_queue.h b/deps/nghttp2/lib/nghttp2_queue.h +index a06fa6c7..c63897c0 100644 +--- a/deps/nghttp2/lib/nghttp2_queue.h ++++ b/deps/nghttp2/lib/nghttp2_queue.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include "config.h" +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -48,4 +48,4 @@ void *nghttp2_queue_front(nghttp2_queue *queue); + void *nghttp2_queue_back(nghttp2_queue *queue); + int nghttp2_queue_empty(nghttp2_queue *queue); + +-#endif /* NGHTTP2_QUEUE_H */ ++#endif /* !defined(NGHTTP2_QUEUE_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_ratelim.h b/deps/nghttp2/lib/nghttp2_ratelim.h +index 866ed3f0..d1097f2f 100644 +--- a/deps/nghttp2/lib/nghttp2_ratelim.h ++++ b/deps/nghttp2/lib/nghttp2_ratelim.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -54,4 +54,4 @@ void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp); + succeeds, or -1. */ + int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n); + +-#endif /* NGHTTP2_RATELIM_H */ ++#endif /* !defined(NGHTTP2_RATELIM_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_rcbuf.h b/deps/nghttp2/lib/nghttp2_rcbuf.h +index 6814e709..ef82e1b3 100644 +--- a/deps/nghttp2/lib/nghttp2_rcbuf.h ++++ b/deps/nghttp2/lib/nghttp2_rcbuf.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -77,4 +77,4 @@ int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src, + */ + void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf); + +-#endif /* NGHTTP2_RCBUF_H */ ++#endif /* !defined(NGHTTP2_RCBUF_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c +index df33a89e..0fbcc930 100644 +--- a/deps/nghttp2/lib/nghttp2_session.c ++++ b/deps/nghttp2/lib/nghttp2_session.c +@@ -41,6 +41,8 @@ + #include "nghttp2_debug.h" + #include "nghttp2_submit.h" + ++nghttp2_stream nghttp2_stream_root; ++ + /* + * Returns non-zero if the number of outgoing opened streams is larger + * than or equal to +@@ -146,11 +148,6 @@ static int session_detect_idle_stream(nghttp2_session *session, + return 0; + } + +-static int session_no_rfc7540_pri_no_fallback(nghttp2_session *session) { +- return session->pending_no_rfc7540_priorities == 1 && +- !session->fallback_rfc7540_priorities; +-} +- + static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) { + return (ext_types[type / 8] & (1 << (type & 0x7))) > 0; + } +@@ -441,6 +438,7 @@ static int session_new(nghttp2_session **session_ptr, + size_t max_deflate_dynamic_table_size = + NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE; + size_t i; ++ uint32_t map_seed; + + if (mem == NULL) { + mem = nghttp2_mem_default(); +@@ -458,10 +456,6 @@ static int session_new(nghttp2_session **session_ptr, + /* next_stream_id is initialized in either + nghttp2_session_client_new2 or nghttp2_session_server_new2 */ + +- nghttp2_stream_init(&(*session_ptr)->root, 0, NGHTTP2_STREAM_FLAG_NONE, +- NGHTTP2_STREAM_IDLE, NGHTTP2_DEFAULT_WEIGHT, 0, 0, NULL, +- mem); +- + (*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE; + (*session_ptr)->recv_window_size = 0; + (*session_ptr)->consumed_size = 0; +@@ -481,6 +475,10 @@ static int session_new(nghttp2_session **session_ptr, + NGHTTP2_DEFAULT_STREAM_RESET_BURST, + NGHTTP2_DEFAULT_STREAM_RESET_RATE); + ++ nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim, ++ NGHTTP2_DEFAULT_GLITCH_BURST, ++ NGHTTP2_DEFAULT_GLITCH_RATE); ++ + if (server) { + (*session_ptr)->server = 1; + } +@@ -548,11 +546,6 @@ static int session_new(nghttp2_session **session_ptr, + max_deflate_dynamic_table_size = option->max_deflate_dynamic_table_size; + } + +- if ((option->opt_set_mask & NGHTTP2_OPT_NO_CLOSED_STREAMS) && +- option->no_closed_streams) { +- (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_CLOSED_STREAMS; +- } +- + if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) { + (*session_ptr)->max_outbound_ack = option->max_outbound_ack; + } +@@ -562,13 +555,6 @@ static int session_new(nghttp2_session **session_ptr, + (*session_ptr)->max_settings = option->max_settings; + } + +- if ((option->opt_set_mask & +- NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES) && +- option->server_fallback_rfc7540_priorities) { +- (*session_ptr)->opt_flags |= +- NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES; +- } +- + if ((option->opt_set_mask & + NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) && + option->no_rfc9113_leading_and_trailing_ws_validation) { +@@ -585,6 +571,11 @@ static int session_new(nghttp2_session **session_ptr, + if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) { + (*session_ptr)->max_continuations = option->max_continuations; + } ++ ++ if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) { ++ nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim, ++ option->glitch_burst, option->glitch_rate); ++ } + } + + rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater, +@@ -613,7 +604,13 @@ static int session_new(nghttp2_session **session_ptr, + goto fail_aob_framebuf; + } + +- nghttp2_map_init(&(*session_ptr)->streams, mem); ++ if (callbacks->rand_callback) { ++ callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed)); ++ } else { ++ map_seed = 0; ++ } ++ ++ nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem); + + active_outbound_item_reset(&(*session_ptr)->aob, mem); + +@@ -810,7 +807,6 @@ void nghttp2_session_del(nghttp2_session *session) { + for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) { + nghttp2_pq_free(&session->sched[i].ob_data); + } +- nghttp2_stream_free(&session->root); + + /* Have to free streams first, so that we can check + stream->item->queued */ +@@ -829,82 +825,6 @@ void nghttp2_session_del(nghttp2_session *session) { + nghttp2_mem_free(mem, session); + } + +-int nghttp2_session_reprioritize_stream( +- nghttp2_session *session, nghttp2_stream *stream, +- const nghttp2_priority_spec *pri_spec_in) { +- int rv; +- nghttp2_stream *dep_stream = NULL; +- nghttp2_priority_spec pri_spec_default; +- const nghttp2_priority_spec *pri_spec = pri_spec_in; +- +- assert((!session->server && session->pending_no_rfc7540_priorities != 1) || +- (session->server && !session_no_rfc7540_pri_no_fallback(session))); +- assert(pri_spec->stream_id != stream->stream_id); +- +- if (!nghttp2_stream_in_dep_tree(stream)) { +- return 0; +- } +- +- if (pri_spec->stream_id != 0) { +- dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id); +- +- if (!dep_stream && +- session_detect_idle_stream(session, pri_spec->stream_id)) { +- nghttp2_priority_spec_default_init(&pri_spec_default); +- +- dep_stream = nghttp2_session_open_stream( +- session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, +- NGHTTP2_STREAM_IDLE, NULL); +- +- if (dep_stream == NULL) { +- return NGHTTP2_ERR_NOMEM; +- } +- } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) { +- nghttp2_priority_spec_default_init(&pri_spec_default); +- pri_spec = &pri_spec_default; +- } +- } +- +- if (pri_spec->stream_id == 0) { +- dep_stream = &session->root; +- } else if (nghttp2_stream_dep_find_ancestor(dep_stream, stream)) { +- DEBUGF("stream: cycle detected, dep_stream(%p)=%d stream(%p)=%d\n", +- dep_stream, dep_stream->stream_id, stream, stream->stream_id); +- +- nghttp2_stream_dep_remove_subtree(dep_stream); +- rv = nghttp2_stream_dep_add_subtree(stream->dep_prev, dep_stream); +- if (rv != 0) { +- return rv; +- } +- } +- +- assert(dep_stream); +- +- if (dep_stream == stream->dep_prev && !pri_spec->exclusive) { +- /* This is minor optimization when just weight is changed. */ +- nghttp2_stream_change_weight(stream, pri_spec->weight); +- +- return 0; +- } +- +- nghttp2_stream_dep_remove_subtree(stream); +- +- /* We have to update weight after removing stream from tree */ +- stream->weight = pri_spec->weight; +- +- if (pri_spec->exclusive) { +- rv = nghttp2_stream_dep_insert_subtree(dep_stream, stream); +- } else { +- rv = nghttp2_stream_dep_add_subtree(dep_stream, stream); +- } +- +- if (rv != 0) { +- return rv; +- } +- +- return 0; +-} +- + static uint64_t pq_get_first_cycle(nghttp2_pq *pq) { + nghttp2_stream *stream; + +@@ -923,7 +843,6 @@ static int session_ob_data_push(nghttp2_session *session, + int inc; + nghttp2_pq *pq; + +- assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES); + assert(stream->queued == 0); + + urgency = nghttp2_extpri_uint8_urgency(stream->extpri); +@@ -952,7 +871,6 @@ static void session_ob_data_remove(nghttp2_session *session, + nghttp2_stream *stream) { + uint32_t urgency; + +- assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES); + assert(stream->queued == 1); + + urgency = nghttp2_extpri_uint8_urgency(stream->extpri); +@@ -969,14 +887,7 @@ static int session_attach_stream_item(nghttp2_session *session, + nghttp2_outbound_item *item) { + int rv; + +- rv = nghttp2_stream_attach_item(stream, item); +- if (rv != 0) { +- return rv; +- } +- +- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) { +- return 0; +- } ++ nghttp2_stream_attach_item(stream, item); + + rv = session_ob_data_push(session, stream); + if (rv != 0) { +@@ -992,8 +903,7 @@ static void session_detach_stream_item(nghttp2_session *session, + nghttp2_stream *stream) { + nghttp2_stream_detach_item(stream); + +- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || +- !stream->queued) { ++ if (!stream->queued) { + return; + } + +@@ -1004,8 +914,7 @@ static void session_defer_stream_item(nghttp2_session *session, + nghttp2_stream *stream, uint8_t flags) { + nghttp2_stream_defer_item(stream, flags); + +- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || +- !stream->queued) { ++ if (!stream->queued) { + return; + } + +@@ -1015,15 +924,9 @@ static void session_defer_stream_item(nghttp2_session *session, + static int session_resume_deferred_stream_item(nghttp2_session *session, + nghttp2_stream *stream, + uint8_t flags) { +- int rv; ++ nghttp2_stream_resume_deferred_item(stream, flags); + +- rv = nghttp2_stream_resume_deferred_item(stream, flags); +- if (rv != 0) { +- return rv; +- } +- +- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || +- (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL)) { ++ if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) { + return 0; + } + +@@ -1168,7 +1071,6 @@ int nghttp2_session_add_item(nghttp2_session *session, + return 0; + case NGHTTP2_PUSH_PROMISE: { + nghttp2_headers_aux_data *aux_data; +- nghttp2_priority_spec pri_spec; + + aux_data = &item->aux_data.headers; + +@@ -1176,20 +1078,13 @@ int nghttp2_session_add_item(nghttp2_session *session, + return NGHTTP2_ERR_STREAM_CLOSED; + } + +- nghttp2_priority_spec_init(&pri_spec, stream->stream_id, +- NGHTTP2_DEFAULT_WEIGHT, 0); +- + if (!nghttp2_session_open_stream( + session, frame->push_promise.promised_stream_id, +- NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_RESERVED, ++ NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_RESERVED, + aux_data->stream_user_data)) { + return NGHTTP2_ERR_NOMEM; + } + +- /* We don't have to call nghttp2_session_adjust_closed_stream() +- here, since stream->stream_id is local stream_id, and it does +- not affect closed stream count. */ +- + nghttp2_outbound_queue_push(&session->ob_reg, item); + item->queued = 1; + +@@ -1213,6 +1108,15 @@ int nghttp2_session_add_item(nghttp2_session *session, + + int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, + uint32_t error_code) { ++ return nghttp2_session_add_rst_stream_continue( ++ session, stream_id, error_code, ++ /* continue_without_stream = */ 1); ++} ++ ++int nghttp2_session_add_rst_stream_continue(nghttp2_session *session, ++ int32_t stream_id, ++ uint32_t error_code, ++ int continue_without_stream) { + int rv; + nghttp2_outbound_item *item; + nghttp2_frame *frame; +@@ -1269,6 +1173,12 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, + } + } + ++ /* To keep the old behaviour, do not fail if stream was not ++ found. */ ++ if (!continue_without_stream && !stream) { ++ return 0; ++ } ++ + item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); + if (item == NULL) { + return NGHTTP2_ERR_NOMEM; +@@ -1290,15 +1200,11 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, + + nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + int32_t stream_id, uint8_t flags, +- nghttp2_priority_spec *pri_spec_in, + nghttp2_stream_state initial_state, + void *stream_user_data) { + int rv; + nghttp2_stream *stream; +- nghttp2_stream *dep_stream = NULL; + int stream_alloc = 0; +- nghttp2_priority_spec pri_spec_default; +- nghttp2_priority_spec *pri_spec = pri_spec_in; + nghttp2_mem *mem; + + mem = &session->mem; +@@ -1311,23 +1217,9 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + + if (stream) { + assert(stream->state == NGHTTP2_STREAM_IDLE); +- assert((stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || +- nghttp2_stream_in_dep_tree(stream)); +- +- nghttp2_session_detach_idle_stream(session, stream); +- +- if (nghttp2_stream_in_dep_tree(stream)) { +- assert(!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)); ++ assert(initial_state != NGHTTP2_STREAM_IDLE); + +- rv = nghttp2_stream_dep_remove(stream); +- if (rv != 0) { +- return NULL; +- } +- +- if (session_no_rfc7540_pri_no_fallback(session)) { +- stream->flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES; +- } +- } ++ --session->num_idle_streams; + } else { + stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream)); + if (stream == NULL) { +@@ -1337,69 +1229,16 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + stream_alloc = 1; + } + +- if (session_no_rfc7540_pri_no_fallback(session) || +- session->remote_settings.no_rfc7540_priorities == 1) { +- /* For client which has not received server +- SETTINGS_NO_RFC7540_PRIORITIES = 1, send a priority signal +- opportunistically. */ +- if (session->server || +- session->remote_settings.no_rfc7540_priorities == 1) { +- nghttp2_priority_spec_default_init(&pri_spec_default); +- pri_spec = &pri_spec_default; +- } +- +- if (session->pending_no_rfc7540_priorities == 1) { +- flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES; +- } +- } else if (pri_spec->stream_id != 0) { +- dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id); +- +- if (!dep_stream && +- session_detect_idle_stream(session, pri_spec->stream_id)) { +- /* Depends on idle stream, which does not exist in memory. +- Assign default priority for it. */ +- nghttp2_priority_spec_default_init(&pri_spec_default); +- +- dep_stream = nghttp2_session_open_stream( +- session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, +- NGHTTP2_STREAM_IDLE, NULL); +- +- if (dep_stream == NULL) { +- if (stream_alloc) { +- nghttp2_mem_free(mem, stream); +- } +- +- return NULL; +- } +- } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) { +- /* If dep_stream is not part of dependency tree, stream will get +- default priority. This handles the case when +- pri_spec->stream_id == stream_id. This happens because we +- don't check pri_spec->stream_id against new stream ID in +- nghttp2_submit_request. This also handles the case when idle +- stream created by PRIORITY frame was opened. Somehow we +- first remove the idle stream from dependency tree. This is +- done to simplify code base, but ideally we should retain old +- dependency. But I'm not sure this adds values. */ +- nghttp2_priority_spec_default_init(&pri_spec_default); +- pri_spec = &pri_spec_default; +- } +- } +- + if (initial_state == NGHTTP2_STREAM_RESERVED) { + flags |= NGHTTP2_STREAM_FLAG_PUSH; + } + + if (stream_alloc) { + nghttp2_stream_init(stream, stream_id, flags, initial_state, +- pri_spec->weight, + (int32_t)session->remote_settings.initial_window_size, + (int32_t)session->local_settings.initial_window_size, +- stream_user_data, mem); +- +- if (session_no_rfc7540_pri_no_fallback(session)) { +- stream->seq = session->stream_seq++; +- } ++ stream_user_data); ++ stream->seq = session->stream_seq++; + + rv = nghttp2_map_insert(&session->streams, stream_id, stream); + if (rv != 0) { +@@ -1410,7 +1249,6 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + } else { + stream->flags = flags; + stream->state = initial_state; +- stream->weight = pri_spec->weight; + stream->stream_user_data = stream_user_data; + } + +@@ -1428,9 +1266,7 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + limit. That is one of the DOS vector. */ + break; + case NGHTTP2_STREAM_IDLE: +- /* Idle stream does not count toward the concurrent streams limit. +- This is used as anchor node in dependency tree. */ +- nghttp2_session_keep_idle_stream(session, stream); ++ ++session->num_idle_streams; + break; + default: + if (nghttp2_session_is_my_stream_id(session, stream_id)) { +@@ -1440,31 +1276,11 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + } + } + +- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { +- return stream; +- } +- +- if (pri_spec->stream_id == 0) { +- dep_stream = &session->root; +- } +- +- assert(dep_stream); +- +- if (pri_spec->exclusive) { +- rv = nghttp2_stream_dep_insert(dep_stream, stream); +- if (rv != 0) { +- return NULL; +- } +- } else { +- nghttp2_stream_dep_add(dep_stream, stream); +- } +- + return stream; + } + + int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, + uint32_t error_code) { +- int rv; + nghttp2_stream *stream; + nghttp2_mem *mem; + int is_my_stream_id; +@@ -1528,207 +1344,26 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, + /* Closes both directions just in case they are not closed yet */ + stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED; + +- if (session->pending_no_rfc7540_priorities == 1) { +- return nghttp2_session_destroy_stream(session, stream); +- } +- +- if ((session->opt_flags & NGHTTP2_OPTMASK_NO_CLOSED_STREAMS) == 0 && +- session->server && !is_my_stream_id && +- nghttp2_stream_in_dep_tree(stream)) { +- /* On server side, retain stream at most MAX_CONCURRENT_STREAMS +- combined with the current active incoming streams to make +- dependency tree work better. */ +- nghttp2_session_keep_closed_stream(session, stream); +- } else { +- rv = nghttp2_session_destroy_stream(session, stream); +- if (rv != 0) { +- return rv; +- } +- } ++ nghttp2_session_destroy_stream(session, stream); + + return 0; + } + +-int nghttp2_session_destroy_stream(nghttp2_session *session, +- nghttp2_stream *stream) { ++void nghttp2_session_destroy_stream(nghttp2_session *session, ++ nghttp2_stream *stream) { + nghttp2_mem *mem; +- int rv; + + DEBUGF("stream: destroy closed stream(%p)=%d\n", stream, stream->stream_id); + + mem = &session->mem; + +- if (nghttp2_stream_in_dep_tree(stream)) { +- rv = nghttp2_stream_dep_remove(stream); +- if (rv != 0) { +- return rv; +- } +- } +- +- if (stream->queued && +- (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) { ++ if (stream->queued) { + session_ob_data_remove(session, stream); + } + + nghttp2_map_remove(&session->streams, stream->stream_id); + nghttp2_stream_free(stream); + nghttp2_mem_free(mem, stream); +- +- return 0; +-} +- +-void nghttp2_session_keep_closed_stream(nghttp2_session *session, +- nghttp2_stream *stream) { +- DEBUGF("stream: keep closed stream(%p)=%d, state=%d\n", stream, +- stream->stream_id, stream->state); +- +- if (session->closed_stream_tail) { +- session->closed_stream_tail->closed_next = stream; +- stream->closed_prev = session->closed_stream_tail; +- } else { +- session->closed_stream_head = stream; +- } +- session->closed_stream_tail = stream; +- +- ++session->num_closed_streams; +-} +- +-void nghttp2_session_keep_idle_stream(nghttp2_session *session, +- nghttp2_stream *stream) { +- DEBUGF("stream: keep idle stream(%p)=%d, state=%d\n", stream, +- stream->stream_id, stream->state); +- +- if (session->idle_stream_tail) { +- session->idle_stream_tail->closed_next = stream; +- stream->closed_prev = session->idle_stream_tail; +- } else { +- session->idle_stream_head = stream; +- } +- session->idle_stream_tail = stream; +- +- ++session->num_idle_streams; +-} +- +-void nghttp2_session_detach_idle_stream(nghttp2_session *session, +- nghttp2_stream *stream) { +- nghttp2_stream *prev_stream, *next_stream; +- +- DEBUGF("stream: detach idle stream(%p)=%d, state=%d\n", stream, +- stream->stream_id, stream->state); +- +- prev_stream = stream->closed_prev; +- next_stream = stream->closed_next; +- +- if (prev_stream) { +- prev_stream->closed_next = next_stream; +- } else { +- session->idle_stream_head = next_stream; +- } +- +- if (next_stream) { +- next_stream->closed_prev = prev_stream; +- } else { +- session->idle_stream_tail = prev_stream; +- } +- +- stream->closed_prev = NULL; +- stream->closed_next = NULL; +- +- --session->num_idle_streams; +-} +- +-int nghttp2_session_adjust_closed_stream(nghttp2_session *session) { +- size_t num_stream_max; +- int rv; +- +- if (session->local_settings.max_concurrent_streams == +- NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS) { +- num_stream_max = session->pending_local_max_concurrent_stream; +- } else { +- num_stream_max = session->local_settings.max_concurrent_streams; +- } +- +- DEBUGF("stream: adjusting kept closed streams num_closed_streams=%zu, " +- "num_incoming_streams=%zu, max_concurrent_streams=%zu\n", +- session->num_closed_streams, session->num_incoming_streams, +- num_stream_max); +- +- while (session->num_closed_streams > 0 && +- session->num_closed_streams + session->num_incoming_streams > +- num_stream_max) { +- nghttp2_stream *head_stream; +- nghttp2_stream *next; +- +- head_stream = session->closed_stream_head; +- +- assert(head_stream); +- +- next = head_stream->closed_next; +- +- rv = nghttp2_session_destroy_stream(session, head_stream); +- if (rv != 0) { +- return rv; +- } +- +- /* head_stream is now freed */ +- +- session->closed_stream_head = next; +- +- if (session->closed_stream_head) { +- session->closed_stream_head->closed_prev = NULL; +- } else { +- session->closed_stream_tail = NULL; +- } +- +- --session->num_closed_streams; +- } +- +- return 0; +-} +- +-int nghttp2_session_adjust_idle_stream(nghttp2_session *session) { +- size_t max; +- int rv; +- +- /* Make minimum number of idle streams 16, and maximum 100, which +- are arbitrary chosen numbers. */ +- max = nghttp2_min_uint32( +- 100, +- nghttp2_max_uint32( +- 16, nghttp2_min_uint32(session->local_settings.max_concurrent_streams, +- session->pending_local_max_concurrent_stream))); +- +- DEBUGF("stream: adjusting kept idle streams num_idle_streams=%zu, max=%zu\n", +- session->num_idle_streams, max); +- +- while (session->num_idle_streams > max) { +- nghttp2_stream *head; +- nghttp2_stream *next; +- +- head = session->idle_stream_head; +- assert(head); +- +- next = head->closed_next; +- +- rv = nghttp2_session_destroy_stream(session, head); +- if (rv != 0) { +- return rv; +- } +- +- /* head is now destroyed */ +- +- session->idle_stream_head = next; +- +- if (session->idle_stream_head) { +- session->idle_stream_head->closed_prev = NULL; +- } else { +- session->idle_stream_tail = NULL; +- } +- +- --session->num_idle_streams; +- } +- +- return 0; + } + + /* +@@ -2411,16 +2046,12 @@ static int session_prep_frame(nghttp2_session *session, + + stream = nghttp2_session_open_stream( + session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, +- &frame->headers.pri_spec, NGHTTP2_STREAM_INITIAL, +- aux_data->stream_user_data); ++ NGHTTP2_STREAM_INITIAL, aux_data->stream_user_data); + + if (stream == NULL) { + return NGHTTP2_ERR_NOMEM; + } + +- /* We don't call nghttp2_session_adjust_closed_stream() here, +- since we don't keep closed stream in client side */ +- + rv = session_predicate_request_headers_send(session, item); + if (rv != 0) { + return rv; +@@ -2662,8 +2293,6 @@ static int session_prep_frame(nghttp2_session *session, + + nghttp2_outbound_item * + nghttp2_session_get_next_ob_item(nghttp2_session *session) { +- nghttp2_outbound_item *item; +- + if (nghttp2_outbound_queue_top(&session->ob_urgent)) { + return nghttp2_outbound_queue_top(&session->ob_urgent); + } +@@ -2679,11 +2308,6 @@ nghttp2_session_get_next_ob_item(nghttp2_session *session) { + } + + if (session->remote_window_size > 0) { +- item = nghttp2_stream_next_outbound_item(&session->root); +- if (item) { +- return item; +- } +- + return session_sched_get_next_outbound_item(session); + } + +@@ -2718,11 +2342,6 @@ nghttp2_session_pop_next_ob_item(nghttp2_session *session) { + } + + if (session->remote_window_size > 0) { +- item = nghttp2_stream_next_outbound_item(&session->root); +- if (item) { +- return item; +- } +- + return session_sched_get_next_outbound_item(session); + } + +@@ -2781,7 +2400,6 @@ static int find_stream_on_goaway_func(void *entry, void *ptr) { + nghttp2_session_close_stream() inside nghttp2_map_each(). + Reuse closed_next member.. bad choice? */ + assert(stream->closed_next == NULL); +- assert(stream->closed_prev == NULL); + + if (arg->head) { + stream->closed_next = arg->head; +@@ -2837,11 +2455,6 @@ static void session_reschedule_stream(nghttp2_session *session, + nghttp2_stream *stream) { + stream->last_writelen = stream->item->frame.hd.length; + +- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) { +- nghttp2_stream_reschedule(stream); +- return; +- } +- + if (!session->server) { + return; + } +@@ -3020,37 +2633,6 @@ static int session_after_frame_sent1(nghttp2_session *session) { + } + } + case NGHTTP2_PRIORITY: +- if (session->server || session->pending_no_rfc7540_priorities == 1) { +- return 0; +- } +- +- stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); +- +- if (!stream) { +- if (!session_detect_idle_stream(session, frame->hd.stream_id)) { +- return 0; +- } +- +- stream = nghttp2_session_open_stream( +- session, frame->hd.stream_id, NGHTTP2_FLAG_NONE, +- &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); +- if (!stream) { +- return NGHTTP2_ERR_NOMEM; +- } +- } else { +- rv = nghttp2_session_reprioritize_stream(session, stream, +- &frame->priority.pri_spec); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- } +- +- rv = nghttp2_session_adjust_idle_stream(session); +- +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- + return 0; + case NGHTTP2_RST_STREAM: + rv = nghttp2_session_close_stream(session, frame->hd.stream_id, +@@ -3239,14 +2821,6 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, + aob = &session->aob; + framebufs = &aob->framebufs; + +- /* We may have idle streams more than we expect (e.g., +- nghttp2_session_change_stream_priority() or +- nghttp2_session_create_idle_stream()). Adjust them here. */ +- rv = nghttp2_session_adjust_idle_stream(session); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- + for (;;) { + switch (aob->state) { + case NGHTTP2_OB_POP_ITEM: { +@@ -3698,7 +3272,9 @@ static int session_call_on_invalid_header(nghttp2_session *session, + session, frame, nv->name->base, nv->name->len, nv->value->base, + nv->value->len, nv->flags, session->user_data); + } else { +- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; ++ /* If both callbacks are not set, the invalid field nv is ++ ignored. */ ++ return 0; + } + + if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { +@@ -3783,6 +3359,10 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) { + case NGHTTP2_ERR_HTTP_HEADER: + case NGHTTP2_ERR_HTTP_MESSAGING: + return NGHTTP2_PROTOCOL_ERROR; ++ case NGHTTP2_ERR_INTERNAL: ++ return NGHTTP2_INTERNAL_ERROR; ++ case NGHTTP2_ERR_PUSH_CANCEL: ++ return NGHTTP2_CANCEL; + default: + return NGHTTP2_INTERNAL_ERROR; + } +@@ -3809,17 +3389,32 @@ static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session, + return 0; + } + ++static int session_update_glitch_ratelim(nghttp2_session *session) { ++ if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) { ++ return 0; ++ } ++ ++ nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec()); ++ ++ if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) { ++ return 0; ++ } ++ ++ return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM); ++} ++ + static int session_handle_invalid_stream2(nghttp2_session *session, + int32_t stream_id, + nghttp2_frame *frame, + int lib_error_code) { + int rv; ++ + rv = nghttp2_session_add_rst_stream( + session, stream_id, get_error_code_from_lib_error_code(lib_error_code)); + if (rv != 0) { + return rv; + } +- if (session->callbacks.on_invalid_frame_recv_callback) { ++ if (frame && session->callbacks.on_invalid_frame_recv_callback) { + if (session->callbacks.on_invalid_frame_recv_callback( + session, frame, lib_error_code, session->user_data) != 0) { + return NGHTTP2_ERR_CALLBACK_FAILURE; +@@ -3974,7 +3569,29 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, + + rv2 = session_call_on_invalid_header(session, frame, &nv); + if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { +- rv = NGHTTP2_ERR_HTTP_HEADER; ++ DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n", ++ frame->hd.type, frame->hd.stream_id, (int)nv.name->len, ++ nv.name->base, (int)nv.value->len, nv.value->base); ++ ++ rv = session_call_error_callback( ++ session, NGHTTP2_ERR_HTTP_HEADER, ++ "Invalid HTTP header field was received: frame type: " ++ "%u, stream: %d, name: [%.*s], value: [%.*s]", ++ frame->hd.type, frame->hd.stream_id, (int)nv.name->len, ++ nv.name->base, (int)nv.value->len, nv.value->base); ++ ++ if (nghttp2_is_fatal(rv)) { ++ return rv; ++ } ++ ++ rv = session_handle_invalid_stream2( ++ session, subject_stream->stream_id, frame, ++ NGHTTP2_ERR_HTTP_HEADER); ++ if (nghttp2_is_fatal(rv)) { ++ return rv; ++ } ++ ++ return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + } else { + if (rv2 != 0) { + return rv2; +@@ -4014,13 +3631,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, + return rv; + } + +- rv = +- session_handle_invalid_stream2(session, subject_stream->stream_id, +- frame, NGHTTP2_ERR_HTTP_HEADER); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; ++ return nghttp2_session_terminate_session(session, ++ NGHTTP2_PROTOCOL_ERROR); + } + } + if (rv == 0) { +@@ -4064,7 +3676,6 @@ static int session_end_stream_headers_received(nghttp2_session *session, + + if (session->server && session_enforce_http_messaging(session) && + frame->headers.cat == NGHTTP2_HCAT_REQUEST && +- (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) && + !(stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) && + (stream->http_flags & NGHTTP2_HTTP_FLAG_PRIORITY)) { + rv = session_update_stream_priority(session, stream, stream->http_extpri); +@@ -4134,27 +3745,7 @@ static int session_after_header_block_received(nghttp2_session *session) { + } + } + if (rv != 0) { +- int32_t stream_id; +- +- if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { +- stream_id = frame->push_promise.promised_stream_id; +- } else { +- stream_id = frame->hd.stream_id; +- } +- +- rv = session_handle_invalid_stream2(session, stream_id, frame, +- NGHTTP2_ERR_HTTP_MESSAGING); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- +- if (frame->hd.type == NGHTTP2_HEADERS && +- (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { +- nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); +- /* Don't call nghttp2_session_close_stream_if_shut_rdwr +- because RST_STREAM has been submitted. */ +- } +- return 0; ++ return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); + } + } + +@@ -4253,18 +3844,13 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, + NGHTTP2_ERR_REFUSED_STREAM); + } + +- stream = nghttp2_session_open_stream( +- session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, +- &frame->headers.pri_spec, NGHTTP2_STREAM_OPENING, NULL); ++ stream = nghttp2_session_open_stream(session, frame->hd.stream_id, ++ NGHTTP2_STREAM_FLAG_NONE, ++ NGHTTP2_STREAM_OPENING, NULL); + if (!stream) { + return NGHTTP2_ERR_NOMEM; + } + +- rv = nghttp2_session_adjust_closed_stream(session); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- + session->last_proc_stream_id = session->last_recv_stream_id; + + rv = session_call_on_begin_headers(session, frame); +@@ -4396,104 +3982,33 @@ int nghttp2_session_on_headers_received(nghttp2_session *session, + return NGHTTP2_ERR_IGN_HEADER_BLOCK; + } + +-static int session_process_headers_frame(nghttp2_session *session) { +- nghttp2_inbound_frame *iframe = &session->iframe; +- nghttp2_frame *frame = &iframe->frame; +- nghttp2_stream *stream; +- +- nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos); +- +- stream = nghttp2_session_get_stream(session, frame->hd.stream_id); +- if (!stream) { +- frame->headers.cat = NGHTTP2_HCAT_REQUEST; +- return nghttp2_session_on_request_headers_received(session, frame); +- } +- +- if (stream->state == NGHTTP2_STREAM_RESERVED) { +- frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE; +- return nghttp2_session_on_push_response_headers_received(session, frame, +- stream); +- } +- +- if (stream->state == NGHTTP2_STREAM_OPENING && +- nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { +- frame->headers.cat = NGHTTP2_HCAT_RESPONSE; +- return nghttp2_session_on_response_headers_received(session, frame, stream); +- } +- +- frame->headers.cat = NGHTTP2_HCAT_HEADERS; +- return nghttp2_session_on_headers_received(session, frame, stream); +-} +- +-int nghttp2_session_on_priority_received(nghttp2_session *session, +- nghttp2_frame *frame) { +- int rv; +- nghttp2_stream *stream; +- +- assert(!session_no_rfc7540_pri_no_fallback(session)); +- +- if (frame->hd.stream_id == 0) { +- return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, +- "PRIORITY: stream_id == 0"); +- } +- +- if (frame->priority.pri_spec.stream_id == frame->hd.stream_id) { +- return nghttp2_session_terminate_session_with_reason( +- session, NGHTTP2_PROTOCOL_ERROR, "depend on itself"); +- } +- +- if (!session->server) { +- /* Re-prioritization works only in server */ +- return session_call_on_frame_received(session, frame); +- } +- +- stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); +- +- if (!stream) { +- /* PRIORITY against idle stream can create anchor node in +- dependency tree. */ +- if (!session_detect_idle_stream(session, frame->hd.stream_id)) { +- return 0; +- } +- +- stream = nghttp2_session_open_stream( +- session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, +- &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); +- +- if (stream == NULL) { +- return NGHTTP2_ERR_NOMEM; +- } +- +- rv = nghttp2_session_adjust_idle_stream(session); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- } else { +- rv = nghttp2_session_reprioritize_stream(session, stream, +- &frame->priority.pri_spec); +- +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- +- rv = nghttp2_session_adjust_idle_stream(session); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- } +- +- return session_call_on_frame_received(session, frame); +-} +- +-static int session_process_priority_frame(nghttp2_session *session) { ++static int session_process_headers_frame(nghttp2_session *session) { + nghttp2_inbound_frame *iframe = &session->iframe; + nghttp2_frame *frame = &iframe->frame; ++ nghttp2_stream *stream; ++ ++ nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos); ++ ++ stream = nghttp2_session_get_stream(session, frame->hd.stream_id); ++ if (!stream) { ++ frame->headers.cat = NGHTTP2_HCAT_REQUEST; ++ return nghttp2_session_on_request_headers_received(session, frame); ++ } + +- assert(!session_no_rfc7540_pri_no_fallback(session)); ++ if (stream->state == NGHTTP2_STREAM_RESERVED) { ++ frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE; ++ return nghttp2_session_on_push_response_headers_received(session, frame, ++ stream); ++ } + +- nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos); ++ if (stream->state == NGHTTP2_STREAM_OPENING && ++ nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { ++ frame->headers.cat = NGHTTP2_HCAT_RESPONSE; ++ return nghttp2_session_on_response_headers_received(session, frame, stream); ++ } + +- return nghttp2_session_on_priority_received(session, frame); ++ frame->headers.cat = NGHTTP2_HCAT_HEADERS; ++ return nghttp2_session_on_headers_received(session, frame, stream); + } + + static int session_update_stream_reset_ratelim(nghttp2_session *session) { +@@ -4566,8 +4081,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { + rv = nghttp2_stream_update_remote_initial_window_size( + stream, arg->new_window_size, arg->old_window_size); + if (rv != 0) { +- return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, +- NGHTTP2_FLOW_CONTROL_ERROR); ++ return NGHTTP2_ERR_FLOW_CONTROL; + } + + /* If window size gets positive, push deferred DATA frame to +@@ -4593,6 +4107,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { + * + * NGHTTP2_ERR_NOMEM + * Out of memory. ++ * NGHTTP2_ERR_FLOW_CONTROL ++ * Window size gets out of range. + */ + static int + session_update_remote_initial_window_size(nghttp2_session *session, +@@ -4616,8 +4132,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { + rv = nghttp2_stream_update_local_initial_window_size( + stream, arg->new_window_size, arg->old_window_size); + if (rv != 0) { +- return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, +- NGHTTP2_FLOW_CONTROL_ERROR); ++ return NGHTTP2_ERR_FLOW_CONTROL; + } + + if (stream->window_update_queued) { +@@ -4651,6 +4166,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { + * + * NGHTTP2_ERR_NOMEM + * Out of memory. ++ * NGHTTP2_ERR_FLOW_CONTROL ++ * Window size gets out of range. + */ + static int + session_update_local_initial_window_size(nghttp2_session *session, +@@ -4934,12 +4451,6 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, + + if (session->remote_settings.no_rfc7540_priorities == UINT32_MAX) { + session->remote_settings.no_rfc7540_priorities = 0; +- +- if (session->server && session->pending_no_rfc7540_priorities && +- (session->opt_flags & +- NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES)) { +- session->fallback_rfc7540_priorities = 1; +- } + } + + if (!noack && !session_is_closing(session)) { +@@ -5000,7 +4511,6 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, + int rv; + nghttp2_stream *stream; + nghttp2_stream *promised_stream; +- nghttp2_priority_spec pri_spec; + + if (frame->hd.stream_id == 0) { + return session_inflate_handle_invalid_connection( +@@ -5044,9 +4554,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, + session->max_incoming_reserved_streams) { + /* Currently, client does not retain closed stream, so we don't + check NGHTTP2_SHUT_RD condition here. */ +- +- rv = nghttp2_session_add_rst_stream( +- session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); ++ rv = session_handle_invalid_stream2(session, ++ frame->push_promise.promised_stream_id, ++ NULL, NGHTTP2_ERR_PUSH_CANCEL); + if (rv != 0) { + return rv; + } +@@ -5058,20 +4568,14 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "PUSH_PROMISE: stream closed"); + } + +- nghttp2_priority_spec_init(&pri_spec, stream->stream_id, +- NGHTTP2_DEFAULT_WEIGHT, 0); +- + promised_stream = nghttp2_session_open_stream( + session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE, +- &pri_spec, NGHTTP2_STREAM_RESERVED, NULL); ++ NGHTTP2_STREAM_RESERVED, NULL); + + if (!promised_stream) { + return NGHTTP2_ERR_NOMEM; + } + +- /* We don't call nghttp2_session_adjust_closed_stream(), since we +- don't keep closed stream in client side */ +- + session->last_proc_stream_id = session->last_recv_stream_id; + rv = session_call_on_begin_headers(session, frame); + if (rv != 0) { +@@ -5209,8 +4713,9 @@ static int session_on_stream_window_update_received(nghttp2_session *session, + } + if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < + stream->remote_window_size) { +- return session_handle_invalid_stream(session, frame, +- NGHTTP2_ERR_FLOW_CONTROL); ++ return session_handle_invalid_connection( ++ session, frame, NGHTTP2_ERR_FLOW_CONTROL, ++ "WINDOW_UPDATE: window size overflow"); + } + stream->remote_window_size += frame->window_update.window_size_increment; + +@@ -5292,7 +4797,6 @@ int nghttp2_session_on_priority_update_received(nghttp2_session *session, + nghttp2_frame *frame) { + nghttp2_ext_priority_update *priority_update; + nghttp2_stream *stream; +- nghttp2_priority_spec pri_spec; + nghttp2_extpri extpri; + int rv; + +@@ -5330,10 +4834,9 @@ int nghttp2_session_on_priority_update_received(nghttp2_session *session, + "PRIORITY_UPDATE: max concurrent streams exceeded"); + } + +- nghttp2_priority_spec_default_init(&pri_spec); +- stream = nghttp2_session_open_stream(session, priority_update->stream_id, +- NGHTTP2_FLAG_NONE, &pri_spec, +- NGHTTP2_STREAM_IDLE, NULL); ++ stream = ++ nghttp2_session_open_stream(session, priority_update->stream_id, ++ NGHTTP2_FLAG_NONE, NGHTTP2_STREAM_IDLE, NULL); + if (!stream) { + return NGHTTP2_ERR_NOMEM; + } +@@ -5442,16 +4945,7 @@ int nghttp2_session_on_data_received(nghttp2_session *session, + if (session_enforce_http_messaging(session) && + (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { + if (nghttp2_http_on_remote_end_stream(stream) != 0) { +- rv = nghttp2_session_add_rst_stream(session, stream->stream_id, +- NGHTTP2_PROTOCOL_ERROR); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- +- nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); +- /* Don't call nghttp2_session_close_stream_if_shut_rdwr because +- RST_STREAM has been submitted. */ +- return 0; ++ return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); + } + } + +@@ -5509,8 +5003,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, + rv = adjust_recv_window_size(&stream->recv_window_size, delta_size, + stream->local_window_size); + if (rv != 0) { +- return nghttp2_session_add_rst_stream(session, stream->stream_id, +- NGHTTP2_FLOW_CONTROL_ERROR); ++ return nghttp2_session_terminate_session(session, ++ NGHTTP2_FLOW_CONTROL_ERROR); + } + /* We don't have to send WINDOW_UPDATE if the data received is the + last chunk in the incoming stream. */ +@@ -5869,14 +5363,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + + mem = &session->mem; + +- /* We may have idle streams more than we expect (e.g., +- nghttp2_session_change_stream_priority() or +- nghttp2_session_create_idle_stream()). Adjust them here. */ +- rv = nghttp2_session_adjust_idle_stream(session); +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- + if (!nghttp2_session_want_read(session)) { + return (nghttp2_ssize)inlen; + } +@@ -5980,20 +5466,30 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + busy = 1; + + rv = session_on_data_received_fail_fast(session); ++ if (nghttp2_is_fatal(rv)) { ++ return rv; ++ } ++ + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + if (rv == NGHTTP2_ERR_IGN_PAYLOAD) { + DEBUGF("recv: DATA not allowed stream_id=%d\n", + iframe->frame.hd.stream_id); ++ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + iframe->state = NGHTTP2_IB_IGN_DATA; + break; + } + +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- + rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); + if (rv < 0) { + rv = nghttp2_session_terminate_session_with_reason( +@@ -6011,6 +5507,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + break; + } + ++ /* Empty DATA frame without END_STREAM flag set is ++ suspicious. */ ++ if (iframe->payloadleft == 0 && ++ (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ } ++ + iframe->state = NGHTTP2_IB_READ_DATA; + break; + } +@@ -6063,6 +5573,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + on_begin_frame_called = 1; + + rv = session_process_headers_frame(session); +@@ -6077,8 +5591,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } + + if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { +- rv = nghttp2_session_add_rst_stream( +- session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); ++ rv = session_handle_invalid_stream2( ++ session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); + if (nghttp2_is_fatal(rv)) { + return rv; + } +@@ -6087,6 +5601,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } + + if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; + break; + } +@@ -6107,6 +5630,18 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + break; + } + ++ /* This is deprecated RFC 7540 priorities mechanism which is ++ very unpopular. We do not expect it is received so ++ frequently. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + iframe->state = NGHTTP2_IB_READ_NBYTE; + + inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN); +@@ -6123,7 +5658,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + DEBUGF("recv: WINDOW_UPDATE\n"); + break; + } +-#endif /* DEBUGBUILD */ ++#endif /* defined(DEBUGBUILD) */ + + iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; + +@@ -6279,8 +5814,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (check_ext_type_set(session->user_recv_ext_types, + iframe->frame.hd.type)) { + if (!session->callbacks.unpack_extension_callback) { +- /* Silently ignore unknown frame type. */ ++ /* Receiving too frequent unknown frames is suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + ++ /* Silently ignore unknown frame type. */ + busy = 1; + + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; +@@ -6298,6 +5842,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + case NGHTTP2_ALTSVC: + if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == + 0) { ++ /* Receiving too frequent unknown frames is suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; +@@ -6309,6 +5863,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc; + + if (session->server) { ++ /* Receiving too frequent ALTSVC from client is ++ suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; +@@ -6328,6 +5893,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + break; + case NGHTTP2_ORIGIN: + if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) { ++ /* Receiving too frequent unknown frames is suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; +@@ -6339,6 +5914,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + + if (session->server || iframe->frame.hd.stream_id || + (iframe->frame.hd.flags & 0xf0)) { ++ /* Receiving too frequent invalid frames is ++ suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; +@@ -6365,6 +5951,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + case NGHTTP2_PRIORITY_UPDATE: + if ((session->builtin_recv_ext_types & + NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) { ++ /* Receiving too frequent unknown frames is suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; +@@ -6392,8 +5988,18 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + break; + } + +- if (!session_no_rfc7540_pri_no_fallback(session) || +- iframe->payloadleft > sizeof(iframe->raw_sbuf)) { ++ /* Receiving too frequent PRIORITY_UPDATE is ++ suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ ++ if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) { + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; +@@ -6406,6 +6012,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + + break; + default: ++ /* Receiving too frequent unknown frames is suspicious. */ ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + busy = 1; + + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; +@@ -6429,6 +6045,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + } + } + +@@ -6492,8 +6112,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } + + if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { +- rv = nghttp2_session_add_rst_stream( +- session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); ++ rv = session_handle_invalid_stream2( ++ session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); + if (nghttp2_is_fatal(rv)) { + return rv; + } +@@ -6502,26 +6122,23 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } + + if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { +- iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; +- break; +- } +- +- iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK; +- +- break; +- case NGHTTP2_PRIORITY: +- if (!session_no_rfc7540_pri_no_fallback(session) && +- session->remote_settings.no_rfc7540_priorities != 1) { +- rv = session_process_priority_frame(session); +- if (nghttp2_is_fatal(rv)) { ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } ++ ++ iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; ++ break; + } + ++ iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK; ++ ++ break; ++ case NGHTTP2_PRIORITY: + session_inbound_frame_reset(session); + + break; +@@ -6579,9 +6196,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } + + if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { +- rv = nghttp2_session_add_rst_stream( +- session, iframe->frame.push_promise.promised_stream_id, +- NGHTTP2_INTERNAL_ERROR); ++ rv = session_handle_invalid_stream2( ++ session, iframe->frame.push_promise.promised_stream_id, NULL, ++ NGHTTP2_ERR_INTERNAL); + if (nghttp2_is_fatal(rv)) { + return rv; + } +@@ -6684,6 +6301,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -6706,7 +6327,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } else { + DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n"); + } +-#endif /* DEBUGBUILD */ ++#endif /* defined(DEBUGBUILD) */ + + readlen = inbound_frame_payload_readlen(iframe, in, last); + +@@ -6759,12 +6380,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + iframe->payloadleft -= hd_proclen; + + /* Use promised stream ID for PUSH_PROMISE */ +- rv = nghttp2_session_add_rst_stream( ++ rv = session_handle_invalid_stream2( + session, + iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE + ? iframe->frame.push_promise.promised_stream_id + : iframe->frame.hd.stream_id, +- NGHTTP2_INTERNAL_ERROR); ++ NULL, NGHTTP2_ERR_INTERNAL); + if (nghttp2_is_fatal(rv)) { + return rv; + } +@@ -6811,6 +6432,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + } + session_inbound_frame_reset(session); + +@@ -6934,7 +6559,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + } else { + fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n"); + } +-#endif /* DEBUGBUILD */ ++#endif /* defined(DEBUGBUILD) */ + + if (++session->num_continuations > session->max_continuations) { + return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS; +@@ -6986,6 +6611,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + } else { + iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; + } +@@ -7036,6 +6665,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + } + + busy = 1; +@@ -7052,6 +6685,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + + iframe->frame.data.padlen = (size_t)padlen; + ++ /* Empty DATA frame without END_STREAM flag set is ++ suspicious. */ ++ if (iframe->payloadleft == 0 && ++ (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { ++ rv = session_update_glitch_ratelim(session); ++ if (rv != 0) { ++ return rv; ++ } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ } ++ + iframe->state = NGHTTP2_IB_READ_DATA; + + break; +@@ -7094,6 +6741,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + data_readlen = + inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen); + +@@ -7123,41 +6774,30 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (data_readlen > 0) { + if (session_enforce_http_messaging(session)) { + if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) { +- if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { +- /* Consume all data for connection immediately here */ +- rv = session_update_connection_consumed_size( +- session, (size_t)data_readlen); +- +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- +- if (iframe->state == NGHTTP2_IB_IGN_DATA) { +- return (nghttp2_ssize)inlen; +- } +- } +- +- rv = nghttp2_session_add_rst_stream( +- session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR); ++ rv = nghttp2_session_terminate_session(session, ++ NGHTTP2_PROTOCOL_ERROR); + if (nghttp2_is_fatal(rv)) { + return rv; + } +- busy = 1; +- iframe->state = NGHTTP2_IB_IGN_DATA; +- break; ++ ++ return (nghttp2_ssize)inlen; + } + } + if (session->callbacks.on_data_chunk_recv_callback) { + rv = session->callbacks.on_data_chunk_recv_callback( + session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, + in - readlen, (size_t)data_readlen, session->user_data); +- if (rv == NGHTTP2_ERR_PAUSE) { +- return (nghttp2_ssize)(in - first); +- } +- + if (nghttp2_is_fatal(rv)) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ ++ if (rv == NGHTTP2_ERR_PAUSE) { ++ return (nghttp2_ssize)(in - first); ++ } + } + } + } +@@ -7171,6 +6811,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -7237,6 +6881,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + if (rv != 0) { + busy = 1; + +@@ -7255,6 +6903,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -7283,6 +6935,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -7404,9 +7060,7 @@ int nghttp2_session_want_write(nghttp2_session *session) { + */ + return session->aob.item || nghttp2_outbound_queue_top(&session->ob_urgent) || + nghttp2_outbound_queue_top(&session->ob_reg) || +- ((!nghttp2_pq_empty(&session->root.obq) || +- !session_sched_empty(session)) && +- session->remote_window_size > 0) || ++ (!session_sched_empty(session) && session->remote_window_size > 0) || + (nghttp2_outbound_queue_top(&session->ob_syn) && + !session_is_outgoing_concurrent_streams_max(session)); + } +@@ -8046,7 +7700,6 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session, + nghttp2_settings_entry *iv; + size_t niv; + int rv; +- nghttp2_priority_spec pri_spec; + nghttp2_mem *mem; + + mem = &session->mem; +@@ -8083,18 +7736,13 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session, + return rv; + } + +- nghttp2_priority_spec_default_init(&pri_spec); +- + stream = nghttp2_session_open_stream( +- session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_OPENING, ++ session, 1, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_OPENING, + session->server ? NULL : stream_user_data); + if (stream == NULL) { + return NGHTTP2_ERR_NOMEM; + } + +- /* We don't call nghttp2_session_adjust_closed_stream(), since this +- should be the first stream open. */ +- + if (session->server) { + nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); + session->last_recv_stream_id = 1; +@@ -8293,14 +7941,16 @@ int32_t nghttp2_session_get_last_proc_stream_id(nghttp2_session *session) { + nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session, + int32_t stream_id) { + if (stream_id == 0) { +- return &session->root; ++ return &nghttp2_stream_root; + } + + return nghttp2_session_get_stream_raw(session, stream_id); + } + + nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) { +- return &session->root; ++ (void)session; ++ ++ return &nghttp2_stream_root; + } + + int nghttp2_session_check_server_session(nghttp2_session *session) { +@@ -8310,75 +7960,20 @@ int nghttp2_session_check_server_session(nghttp2_session *session) { + int nghttp2_session_change_stream_priority( + nghttp2_session *session, int32_t stream_id, + const nghttp2_priority_spec *pri_spec) { +- int rv; +- nghttp2_stream *stream; +- nghttp2_priority_spec pri_spec_copy; +- +- if (session->pending_no_rfc7540_priorities == 1) { +- return 0; +- } +- +- if (stream_id == 0 || stream_id == pri_spec->stream_id) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- stream = nghttp2_session_get_stream_raw(session, stream_id); +- if (!stream) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- pri_spec_copy = *pri_spec; +- nghttp2_priority_spec_normalize_weight(&pri_spec_copy); +- +- rv = nghttp2_session_reprioritize_stream(session, stream, &pri_spec_copy); +- +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } ++ (void)session; ++ (void)stream_id; ++ (void)pri_spec; + +- /* We don't intentionally call nghttp2_session_adjust_idle_stream() +- so that idle stream created by this function, and existing ones +- are kept for application. We will adjust number of idle stream +- in nghttp2_session_mem_send2 or nghttp2_session_mem_recv2 is +- called. */ + return 0; + } + + int nghttp2_session_create_idle_stream(nghttp2_session *session, + int32_t stream_id, + const nghttp2_priority_spec *pri_spec) { +- nghttp2_stream *stream; +- nghttp2_priority_spec pri_spec_copy; +- +- if (session->pending_no_rfc7540_priorities == 1) { +- return 0; +- } +- +- if (stream_id == 0 || stream_id == pri_spec->stream_id || +- !session_detect_idle_stream(session, stream_id)) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- stream = nghttp2_session_get_stream_raw(session, stream_id); +- if (stream) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- pri_spec_copy = *pri_spec; +- nghttp2_priority_spec_normalize_weight(&pri_spec_copy); +- +- stream = +- nghttp2_session_open_stream(session, stream_id, NGHTTP2_STREAM_FLAG_NONE, +- &pri_spec_copy, NGHTTP2_STREAM_IDLE, NULL); +- if (!stream) { +- return NGHTTP2_ERR_NOMEM; +- } ++ (void)session; ++ (void)stream_id; ++ (void)pri_spec; + +- /* We don't intentionally call nghttp2_session_adjust_idle_stream() +- so that idle stream created by this function, and existing ones +- are kept for application. We will adjust number of idle stream +- in nghttp2_session_mem_send2 or nghttp2_session_mem_recv2 is +- called. */ + return 0; + } + +diff --git a/deps/nghttp2/lib/nghttp2_session.h b/deps/nghttp2/lib/nghttp2_session.h +index ef8f7b27..edbef80d 100644 +--- a/deps/nghttp2/lib/nghttp2_session.h ++++ b/deps/nghttp2/lib/nghttp2_session.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include "nghttp2_map.h" +@@ -45,6 +45,8 @@ + preface handling. */ + extern int nghttp2_enable_strict_preface; + ++extern nghttp2_stream nghttp2_stream_root; ++ + /* + * Option flags. + */ +@@ -53,8 +55,6 @@ typedef enum { + NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1, + NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2, + NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3, +- NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4, +- NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 5, + NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6, + } nghttp2_optmask; + +@@ -89,10 +89,6 @@ typedef struct { + /* The default maximum number of incoming reserved streams */ + #define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200 + +-/* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this +- number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */ +-#define NGHTTP2_MIN_IDLE_STREAMS 16 +- + /* The maximum number of items in outbound queue, which is considered + as flooding caused by peer. All frames are not considered here. + We only consider PING + ACK and SETTINGS + ACK. This is because +@@ -110,6 +106,10 @@ typedef struct { + #define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 + #define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 + ++/* The default values for glitch rate limiter. */ ++#define NGHTTP2_DEFAULT_GLITCH_BURST 1000 ++#define NGHTTP2_DEFAULT_GLITCH_RATE 33 ++ + /* The default max number of CONTINUATION frames following an incoming + HEADER frame. */ + #define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8 +@@ -205,8 +205,6 @@ typedef struct nghttp2_inflight_settings nghttp2_inflight_settings; + + struct nghttp2_session { + nghttp2_map /* */ streams; +- /* root of dependency tree*/ +- nghttp2_stream root; + /* Queue for outbound urgent frames (PING and SETTINGS) */ + nghttp2_outbound_queue ob_urgent; + /* Queue for non-DATA frames */ +@@ -229,26 +227,14 @@ struct nghttp2_session { + /* Memory allocator */ + nghttp2_mem mem; + void *user_data; +- /* Points to the latest incoming closed stream. NULL if there is no +- closed stream. Only used when session is initialized as +- server. */ +- nghttp2_stream *closed_stream_head; +- /* Points to the oldest incoming closed stream. NULL if there is no +- closed stream. Only used when session is initialized as +- server. */ +- nghttp2_stream *closed_stream_tail; +- /* Points to the latest idle stream. NULL if there is no idle +- stream. Only used when session is initialized as server .*/ +- nghttp2_stream *idle_stream_head; +- /* Points to the oldest idle stream. NULL if there is no idle +- stream. Only used when session is initialized as erver. */ +- nghttp2_stream *idle_stream_tail; + /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not + considered as in-flight. */ + nghttp2_inflight_settings *inflight_settings_head; + /* Stream reset rate limiter. If receiving excessive amount of + stream resets, GOAWAY will be sent. */ + nghttp2_ratelim stream_reset_ratelim; ++ /* Rate limiter for all kinds of glitches. */ ++ nghttp2_ratelim glitch_ratelim; + /* Sequential number across all streams to process streams in + FIFO. */ + uint64_t stream_seq; +@@ -276,10 +262,9 @@ struct nghttp2_session { + |closed_stream_head|. The current implementation only keeps + incoming streams and session is initialized as server. */ + size_t num_closed_streams; +- /* The number of idle streams kept in |streams| hash. The idle +- streams can be accessed through doubly linked list +- |idle_stream_head|. The current implementation only keeps idle +- streams if session is initialized as server. */ ++ /* The number of idle streams kept in |streams| hash. The current ++ implementation only keeps idle streams if session is initialized ++ as server. */ + size_t num_idle_streams; + /* The number of bytes allocated for nvbuf */ + size_t nvbuflen; +@@ -362,8 +347,6 @@ struct nghttp2_session { + /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is + effective before it is acknowledged. */ + uint8_t pending_no_rfc7540_priorities; +- /* Turn on fallback to RFC 7540 priorities; for server use only. */ +- uint8_t fallback_rfc7540_priorities; + /* Nonzero if the session is server side. */ + uint8_t server; + /* Flags indicating GOAWAY is sent and/or received. The flags are +@@ -425,6 +408,13 @@ int nghttp2_session_is_my_stream_id(nghttp2_session *session, + int nghttp2_session_add_item(nghttp2_session *session, + nghttp2_outbound_item *item); + ++/* ++ * This function wraps around nghttp2_session_add_rst_stream_continue ++ * with continue_without_stream = 1. ++ */ ++int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, ++ uint32_t error_code); ++ + /* + * Adds RST_STREAM frame for the stream |stream_id| with the error + * code |error_code|. This is a convenient function built on top of +@@ -432,7 +422,9 @@ int nghttp2_session_add_item(nghttp2_session *session, + * + * This function simply returns 0 without adding RST_STREAM frame if + * given stream is in NGHTTP2_STREAM_CLOSING state, because multiple +- * RST_STREAM for a stream is redundant. ++ * RST_STREAM for a stream is redundant. It also returns 0 without ++ * adding the frame if |continue_without_stream| is nonzero, and ++ * stream was already gone. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: +@@ -440,8 +432,10 @@ int nghttp2_session_add_item(nghttp2_session *session, + * NGHTTP2_ERR_NOMEM + * Out of memory. + */ +-int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, +- uint32_t error_code); ++int nghttp2_session_add_rst_stream_continue(nghttp2_session *session, ++ int32_t stream_id, ++ uint32_t error_code, ++ int continue_without_stream); + + /* + * Adds PING frame. This is a convenient function built on top of +@@ -527,15 +521,9 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags, + * + * This function returns a pointer to created new stream object, or + * NULL. +- * +- * This function adjusts neither the number of closed streams or idle +- * streams. The caller should manually call +- * nghttp2_session_adjust_closed_stream() or +- * nghttp2_session_adjust_idle_stream() respectively. + */ + nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + int32_t stream_id, uint8_t flags, +- nghttp2_priority_spec *pri_spec, + nghttp2_stream_state initial_state, + void *stream_user_data); + +@@ -544,11 +532,6 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, + * is indicated by the |error_code|. When closing the stream, + * on_stream_close_callback will be called. + * +- * If the session is initialized as server and |stream| is incoming +- * stream, stream is just marked closed and this function calls +- * nghttp2_session_keep_closed_stream() with |stream|. Otherwise, +- * |stream| will be deleted from memory. +- * + * This function returns 0 if it succeeds, or one the following + * negative error codes: + * +@@ -565,63 +548,9 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, + /* + * Deletes |stream| from memory. After this function returns, stream + * cannot be accessed. +- * +- * This function returns 0 if it succeeds, or one the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_session_destroy_stream(nghttp2_session *session, +- nghttp2_stream *stream); +- +-/* +- * Tries to keep incoming closed stream |stream|. Due to the +- * limitation of maximum number of streams in memory, |stream| is not +- * closed and just deleted from memory (see +- * nghttp2_session_destroy_stream). +- */ +-void nghttp2_session_keep_closed_stream(nghttp2_session *session, +- nghttp2_stream *stream); +- +-/* +- * Appends |stream| to linked list |session->idle_stream_head|. We +- * apply fixed limit for list size. To fit into that limit, one or +- * more oldest streams are removed from list as necessary. + */ +-void nghttp2_session_keep_idle_stream(nghttp2_session *session, +- nghttp2_stream *stream); +- +-/* +- * Detaches |stream| from idle streams linked list. +- */ +-void nghttp2_session_detach_idle_stream(nghttp2_session *session, +- nghttp2_stream *stream); +- +-/* +- * Deletes closed stream to ensure that number of incoming streams +- * including active and closed is in the maximum number of allowed +- * stream. +- * +- * This function returns 0 if it succeeds, or one the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_session_adjust_closed_stream(nghttp2_session *session); +- +-/* +- * Deletes idle stream to ensure that number of idle streams is in +- * certain limit. +- * +- * This function returns 0 if it succeeds, or one the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_session_adjust_idle_stream(nghttp2_session *session); ++void nghttp2_session_destroy_stream(nghttp2_session *session, ++ nghttp2_stream *stream); + + /* + * If further receptions and transmissions over the stream |stream_id| +@@ -915,24 +844,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session, + nghttp2_settings_entry *iv, + size_t niv); + +-/* +- * Re-prioritize |stream|. The new priority specification is +- * |pri_spec|. Caller must ensure that stream->hd.stream_id != +- * pri_spec->stream_id. +- * +- * This function does not adjust the number of idle streams. The +- * caller should call nghttp2_session_adjust_idle_stream() later. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_session_reprioritize_stream(nghttp2_session *session, +- nghttp2_stream *stream, +- const nghttp2_priority_spec *pri_spec); +- + /* + * Terminates current |session| with the |error_code|. The |reason| + * is NULL-terminated debug string. +@@ -981,4 +892,4 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, + size_t delta_size, + int send_window_update); + +-#endif /* NGHTTP2_SESSION_H */ ++#endif /* !defined(NGHTTP2_SESSION_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_stream.c b/deps/nghttp2/lib/nghttp2_stream.c +index f2362447..0f2d3658 100644 +--- a/deps/nghttp2/lib/nghttp2_stream.c ++++ b/deps/nghttp2/lib/nghttp2_stream.c +@@ -25,45 +25,17 @@ + #include "nghttp2_stream.h" + + #include +-#include + + #include "nghttp2_session.h" + #include "nghttp2_helper.h" + #include "nghttp2_debug.h" + #include "nghttp2_frame.h" + +-/* Maximum distance between any two stream's cycle in the same +- priority queue. Imagine stream A's cycle is A, and stream B's +- cycle is B, and A < B. The cycle is unsigned 32 bit integer, it +- may get overflow. Because of how we calculate the next cycle +- value, if B - A is less than or equals to +- NGHTTP2_MAX_CYCLE_DISTANCE, A and B are in the same scale, in other +- words, B is really greater than or equal to A. Otherwise, A is a +- result of overflow, and it is actually A > B if we consider that +- fact. */ +-#define NGHTTP2_MAX_CYCLE_DISTANCE \ +- ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX * 256 + 255) +- +-static int stream_less(const void *lhsx, const void *rhsx) { +- const nghttp2_stream *lhs, *rhs; +- +- lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry); +- rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry); +- +- if (lhs->cycle == rhs->cycle) { +- return lhs->seq < rhs->seq; +- } +- +- return rhs->cycle - lhs->cycle <= NGHTTP2_MAX_CYCLE_DISTANCE; +-} +- + void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, + uint8_t flags, nghttp2_stream_state initial_state, +- int32_t weight, int32_t remote_initial_window_size, ++ int32_t remote_initial_window_size, + int32_t local_initial_window_size, +- void *stream_user_data, nghttp2_mem *mem) { +- nghttp2_pq_init(&stream->obq, stream_less, mem); +- ++ void *stream_user_data) { + stream->stream_id = stream_id; + stream->flags = flags; + stream->state = initial_state; +@@ -77,428 +49,36 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, + stream->recv_reduction = 0; + stream->window_update_queued = 0; + +- stream->dep_prev = NULL; +- stream->dep_next = NULL; +- stream->sib_prev = NULL; +- stream->sib_next = NULL; +- +- stream->closed_prev = NULL; + stream->closed_next = NULL; + +- stream->weight = weight; +- stream->sum_dep_weight = 0; +- + stream->http_flags = NGHTTP2_HTTP_FLAG_NONE; + stream->content_length = -1; + stream->recv_content_length = 0; + stream->status_code = -1; + + stream->queued = 0; +- stream->descendant_last_cycle = 0; + stream->cycle = 0; + stream->pending_penalty = 0; +- stream->descendant_next_seq = 0; + stream->seq = 0; + stream->last_writelen = 0; + + stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY; + } + +-void nghttp2_stream_free(nghttp2_stream *stream) { +- nghttp2_pq_free(&stream->obq); +- /* We don't free stream->item. If it is assigned to aob, then +- active_outbound_item_reset() will delete it. Otherwise, +- nghttp2_stream_close() or session_del() will delete it. */ +-} ++void nghttp2_stream_free(nghttp2_stream *stream) { (void)stream; } + + void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) { + stream->shut_flags = (uint8_t)(stream->shut_flags | flag); + } + +-/* +- * Returns nonzero if |stream| is active. This function does not take +- * into account its descendants. +- */ +-static int stream_active(nghttp2_stream *stream) { +- return stream->item && +- (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0; +-} +- +-/* +- * Returns nonzero if |stream| or one of its descendants is active +- */ +-static int stream_subtree_active(nghttp2_stream *stream) { +- return stream_active(stream) || !nghttp2_pq_empty(&stream->obq); +-} +- +-/* +- * Returns next cycle for |stream|. +- */ +-static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) { +- uint64_t penalty; +- +- penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT + +- stream->pending_penalty; +- +- stream->cycle = last_cycle + penalty / (uint32_t)stream->weight; +- stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight); +-} +- +-static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) { +- int rv; +- +- for (; dep_stream && !stream->queued; +- stream = dep_stream, dep_stream = dep_stream->dep_prev) { +- stream_next_cycle(stream, dep_stream->descendant_last_cycle); +- stream->seq = dep_stream->descendant_next_seq++; +- +- DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id, +- stream->cycle); +- +- DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id, +- dep_stream->stream_id); +- +- rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); +- if (rv != 0) { +- return rv; +- } +- stream->queued = 1; +- } +- +- return 0; +-} +- +-/* +- * Removes |stream| from parent's obq. If removal of |stream| makes +- * parent's obq empty, and parent is not active, then parent is also +- * removed. This process is repeated recursively. +- */ +-static void stream_obq_remove(nghttp2_stream *stream) { +- nghttp2_stream *dep_stream; +- +- dep_stream = stream->dep_prev; +- +- if (!stream->queued) { +- return; +- } +- +- for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { +- DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id, +- dep_stream->stream_id); +- +- nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); +- +- assert(stream->queued); +- +- stream->queued = 0; +- stream->cycle = 0; +- stream->pending_penalty = 0; +- stream->descendant_last_cycle = 0; +- stream->last_writelen = 0; +- +- if (stream_subtree_active(dep_stream)) { +- return; +- } +- } +-} +- +-/* +- * Moves |stream| from |src|'s obq to |dest|'s obq. Removal from +- * |src|'s obq is just done calling nghttp2_pq_remove(), so it does +- * not recursively remove |src| and ancestors, like +- * stream_obq_remove(). +- */ +-static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src, +- nghttp2_stream *stream) { +- if (!stream->queued) { +- return 0; +- } +- +- DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id, +- src->stream_id); +- +- nghttp2_pq_remove(&src->obq, &stream->pq_entry); +- stream->queued = 0; +- +- return stream_obq_push(dest, stream); +-} +- +-void nghttp2_stream_reschedule(nghttp2_stream *stream) { +- nghttp2_stream *dep_stream; +- +- assert(stream->queued); +- +- dep_stream = stream->dep_prev; +- +- for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { +- nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); +- +- stream_next_cycle(stream, dep_stream->descendant_last_cycle); +- stream->seq = dep_stream->descendant_next_seq++; +- +- nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); +- +- DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id, +- stream->cycle); +- +- dep_stream->last_writelen = stream->last_writelen; +- } +-} +- +-void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) { +- nghttp2_stream *dep_stream; +- uint64_t last_cycle; +- int32_t old_weight; +- uint64_t wlen_penalty; +- +- if (stream->weight == weight) { +- return; +- } +- +- old_weight = stream->weight; +- stream->weight = weight; +- +- dep_stream = stream->dep_prev; +- +- if (!dep_stream) { +- return; +- } +- +- dep_stream->sum_dep_weight += weight - old_weight; +- +- if (!stream->queued) { +- return; +- } +- +- nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); +- +- wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT; +- +- /* Compute old stream->pending_penalty we used to calculate +- stream->cycle */ +- stream->pending_penalty = +- (uint32_t)((stream->pending_penalty + (uint32_t)old_weight - +- (wlen_penalty % (uint32_t)old_weight)) % +- (uint32_t)old_weight); +- +- last_cycle = stream->cycle - +- (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight; +- +- /* Now we have old stream->pending_penalty and new stream->weight in +- place */ +- stream_next_cycle(stream, last_cycle); +- +- if (dep_stream->descendant_last_cycle - stream->cycle <= +- NGHTTP2_MAX_CYCLE_DISTANCE) { +- stream->cycle = dep_stream->descendant_last_cycle; +- } +- +- /* Continue to use same stream->seq */ +- +- nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); +- +- DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id, +- stream->cycle); +-} +- +-static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) { +- for (; stream->sib_next; stream = stream->sib_next) +- ; +- +- return stream; +-} +- +-int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream, +- int32_t weight) { +- weight = stream->weight * weight / stream->sum_dep_weight; +- +- return nghttp2_max_int32(1, weight); +-} +- +-#ifdef STREAM_DEP_DEBUG +- +-static void ensure_inactive(nghttp2_stream *stream) { +- nghttp2_stream *si; +- +- if (stream->queued) { +- fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream, +- stream->stream_id); +- assert(0); +- } +- +- if (stream_active(stream)) { +- fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n", +- stream, stream->stream_id); +- assert(0); +- } +- +- if (!nghttp2_pq_empty(&stream->obq)) { +- fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream, +- stream->stream_id, nghttp2_pq_size(&stream->obq)); +- assert(0); +- } +- +- for (si = stream->dep_next; si; si = si->sib_next) { +- ensure_inactive(si); +- } +-} +- +-static void check_queued(nghttp2_stream *stream) { +- nghttp2_stream *si; +- int queued; +- +- if (stream->queued) { +- if (!stream_subtree_active(stream)) { +- fprintf(stderr, +- "stream(%p)=%d, stream->queued == 1, but " +- "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n", +- stream, stream->stream_id, stream_active(stream), +- nghttp2_pq_size(&stream->obq)); +- assert(0); +- } +- if (!stream_active(stream)) { +- queued = 0; +- for (si = stream->dep_next; si; si = si->sib_next) { +- if (si->queued) { +- ++queued; +- } +- } +- if (queued == 0) { +- fprintf(stderr, +- "stream(%p)=%d, stream->queued == 1, and " +- "!stream_active(), but no descendants is queued\n", +- stream, stream->stream_id); +- assert(0); +- } +- } +- +- for (si = stream->dep_next; si; si = si->sib_next) { +- check_queued(si); +- } +- } else { +- if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) { +- fprintf(stderr, +- "stream(%p) = %d, stream->queued == 0, but " +- "stream_active(stream) == %d and " +- "nghttp2_pq_size(&stream->obq) = %zu\n", +- stream, stream->stream_id, stream_active(stream), +- nghttp2_pq_size(&stream->obq)); +- assert(0); +- } +- for (si = stream->dep_next; si; si = si->sib_next) { +- ensure_inactive(si); +- } +- } +-} +- +-static void check_sum_dep(nghttp2_stream *stream) { +- nghttp2_stream *si; +- int32_t n = 0; +- for (si = stream->dep_next; si; si = si->sib_next) { +- n += si->weight; +- } +- if (n != stream->sum_dep_weight) { +- fprintf(stderr, "stream(%p)=%d, sum_dep_weight = %d; want %d\n", stream, +- stream->stream_id, n, stream->sum_dep_weight); +- assert(0); +- } +- for (si = stream->dep_next; si; si = si->sib_next) { +- check_sum_dep(si); +- } +-} +- +-static void check_dep_prev(nghttp2_stream *stream) { +- nghttp2_stream *si; +- for (si = stream->dep_next; si; si = si->sib_next) { +- if (si->dep_prev != stream) { +- fprintf(stderr, "si->dep_prev = %p; want %p\n", si->dep_prev, stream); +- assert(0); +- } +- check_dep_prev(si); +- } +-} +- +-#endif /* STREAM_DEP_DEBUG */ +- +-#ifdef STREAM_DEP_DEBUG +-static void validate_tree(nghttp2_stream *stream) { +- nghttp2_stream *si; +- +- if (!stream) { +- return; +- } +- +- for (; stream->dep_prev; stream = stream->dep_prev) +- ; +- +- assert(stream->stream_id == 0); +- assert(!stream->queued); +- +- fprintf(stderr, "checking...\n"); +- if (nghttp2_pq_empty(&stream->obq)) { +- fprintf(stderr, "root obq empty\n"); +- for (si = stream->dep_next; si; si = si->sib_next) { +- ensure_inactive(si); +- } +- } else { +- for (si = stream->dep_next; si; si = si->sib_next) { +- check_queued(si); +- } +- } +- +- check_sum_dep(stream); +- check_dep_prev(stream); +-} +-#else /* !STREAM_DEP_DEBUG */ +-static void validate_tree(nghttp2_stream *stream) { (void)stream; } +-#endif /* !STREAM_DEP_DEBUG*/ +- +-static int stream_update_dep_on_attach_item(nghttp2_stream *stream) { +- int rv; +- +- rv = stream_obq_push(stream->dep_prev, stream); +- if (rv != 0) { +- return rv; +- } +- +- validate_tree(stream); +- return 0; +-} +- +-static void stream_update_dep_on_detach_item(nghttp2_stream *stream) { +- if (nghttp2_pq_empty(&stream->obq)) { +- stream_obq_remove(stream); +- } +- +- validate_tree(stream); +-} +- +-int nghttp2_stream_attach_item(nghttp2_stream *stream, +- nghttp2_outbound_item *item) { +- int rv; +- ++void nghttp2_stream_attach_item(nghttp2_stream *stream, ++ nghttp2_outbound_item *item) { + assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0); + assert(stream->item == NULL); + + DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item); + + stream->item = item; +- +- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { +- return 0; +- } +- +- rv = stream_update_dep_on_attach_item(stream); +- if (rv != 0) { +- /* This may relave stream->queued == 1, but stream->item == NULL. +- But only consequence of this error is fatal one, and session +- destruction. In that execution path, these inconsistency does +- not matter. */ +- stream->item = NULL; +- return rv; +- } +- +- return 0; + } + + void nghttp2_stream_detach_item(nghttp2_stream *stream) { +@@ -506,12 +86,6 @@ void nghttp2_stream_detach_item(nghttp2_stream *stream) { + + stream->item = NULL; + stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL); +- +- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { +- return; +- } +- +- stream_update_dep_on_detach_item(stream); + } + + void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) { +@@ -521,31 +95,16 @@ void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) { + stream->item, flags); + + stream->flags |= flags; +- +- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { +- return; +- } +- +- stream_update_dep_on_detach_item(stream); + } + +-int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) { ++void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, ++ uint8_t flags) { + assert(stream->item); + + DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id, + stream->item, flags); + + stream->flags = (uint8_t)(stream->flags & ~flags); +- +- if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) { +- return 0; +- } +- +- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { +- return 0; +- } +- +- return stream_update_dep_on_attach_item(stream); + } + + int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) { +@@ -591,373 +150,11 @@ void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) { + stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH); + } + +-int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream, +- nghttp2_stream *target) { +- for (; stream; stream = stream->dep_prev) { +- if (stream == target) { +- return 1; +- } +- } +- return 0; +-} +- +-int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream, +- nghttp2_stream *stream) { +- nghttp2_stream *si; +- int rv; +- +- DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream, +- dep_stream->stream_id, stream, stream->stream_id); +- +- stream->sum_dep_weight = dep_stream->sum_dep_weight; +- dep_stream->sum_dep_weight = stream->weight; +- +- if (dep_stream->dep_next) { +- for (si = dep_stream->dep_next; si; si = si->sib_next) { +- si->dep_prev = stream; +- if (si->queued) { +- rv = stream_obq_move(stream, dep_stream, si); +- if (rv != 0) { +- return rv; +- } +- } +- } +- +- if (stream_subtree_active(stream)) { +- rv = stream_obq_push(dep_stream, stream); +- if (rv != 0) { +- return rv; +- } +- } +- +- stream->dep_next = dep_stream->dep_next; +- } +- +- dep_stream->dep_next = stream; +- stream->dep_prev = dep_stream; +- +- validate_tree(stream); +- +- return 0; +-} +- +-static void set_dep_prev(nghttp2_stream *stream, nghttp2_stream *dep) { +- for (; stream; stream = stream->sib_next) { +- stream->dep_prev = dep; +- } +-} +- +-static void link_dep(nghttp2_stream *dep_stream, nghttp2_stream *stream) { +- dep_stream->dep_next = stream; +- if (stream) { +- stream->dep_prev = dep_stream; +- } +-} +- +-static void link_sib(nghttp2_stream *a, nghttp2_stream *b) { +- a->sib_next = b; +- if (b) { +- b->sib_prev = a; +- } +-} +- +-static void insert_link_dep(nghttp2_stream *dep_stream, +- nghttp2_stream *stream) { +- nghttp2_stream *sib_next; +- +- assert(stream->sib_prev == NULL); +- +- sib_next = dep_stream->dep_next; +- +- link_sib(stream, sib_next); +- +- link_dep(dep_stream, stream); +-} +- +-static void unlink_sib(nghttp2_stream *stream) { +- nghttp2_stream *prev, *next, *dep_next; +- +- prev = stream->sib_prev; +- dep_next = stream->dep_next; +- +- assert(prev); +- +- if (dep_next) { +- /* +- * prev--stream(--sib_next--...) +- * | +- * dep_next +- */ +- +- link_sib(prev, dep_next); +- +- set_dep_prev(dep_next, stream->dep_prev); +- +- if (stream->sib_next) { +- link_sib(stream_last_sib(dep_next), stream->sib_next); +- } +- } else { +- /* +- * prev--stream(--sib_next--...) +- */ +- next = stream->sib_next; +- +- prev->sib_next = next; +- +- if (next) { +- next->sib_prev = prev; +- } +- } +-} +- +-static void unlink_dep(nghttp2_stream *stream) { +- nghttp2_stream *prev, *next, *dep_next; +- +- prev = stream->dep_prev; +- dep_next = stream->dep_next; +- +- assert(prev); +- +- if (dep_next) { +- /* +- * prev +- * | +- * stream(--sib_next--...) +- * | +- * dep_next +- */ +- link_dep(prev, dep_next); +- +- set_dep_prev(dep_next, stream->dep_prev); +- +- if (stream->sib_next) { +- link_sib(stream_last_sib(dep_next), stream->sib_next); +- } +- +- } else if (stream->sib_next) { +- /* +- * prev +- * | +- * stream--sib_next +- */ +- next = stream->sib_next; +- +- next->sib_prev = NULL; +- +- link_dep(prev, next); +- } else { +- prev->dep_next = NULL; +- } +-} +- +-void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, +- nghttp2_stream *stream) { +- DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream, +- dep_stream->stream_id, stream, stream->stream_id); +- +- dep_stream->sum_dep_weight += stream->weight; +- +- if (dep_stream->dep_next == NULL) { +- link_dep(dep_stream, stream); +- } else { +- insert_link_dep(dep_stream, stream); +- } +- +- validate_tree(stream); +-} +- +-int nghttp2_stream_dep_remove(nghttp2_stream *stream) { +- nghttp2_stream *dep_prev, *si; +- int32_t sum_dep_weight_delta; +- int rv; +- +- DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id); +- +- /* Distribute weight of |stream| to direct descendants */ +- sum_dep_weight_delta = -stream->weight; +- +- for (si = stream->dep_next; si; si = si->sib_next) { +- si->weight = nghttp2_stream_dep_distributed_weight(stream, si->weight); +- +- sum_dep_weight_delta += si->weight; +- +- if (si->queued) { +- rv = stream_obq_move(stream->dep_prev, stream, si); +- if (rv != 0) { +- return rv; +- } +- } +- } +- +- assert(stream->dep_prev); +- +- dep_prev = stream->dep_prev; +- +- dep_prev->sum_dep_weight += sum_dep_weight_delta; +- +- if (stream->queued) { +- stream_obq_remove(stream); +- } +- +- if (stream->sib_prev) { +- unlink_sib(stream); +- } else { +- unlink_dep(stream); +- } +- +- stream->sum_dep_weight = 0; +- +- stream->dep_prev = NULL; +- stream->dep_next = NULL; +- stream->sib_prev = NULL; +- stream->sib_next = NULL; +- +- validate_tree(dep_prev); +- +- return 0; +-} +- +-int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, +- nghttp2_stream *stream) { +- nghttp2_stream *last_sib; +- nghttp2_stream *dep_next; +- nghttp2_stream *si; +- int rv; +- +- DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n", +- dep_stream, dep_stream->stream_id, stream, stream->stream_id); +- +- stream->sum_dep_weight += dep_stream->sum_dep_weight; +- dep_stream->sum_dep_weight = stream->weight; +- +- if (dep_stream->dep_next) { +- dep_next = dep_stream->dep_next; +- +- link_dep(dep_stream, stream); +- +- if (stream->dep_next) { +- last_sib = stream_last_sib(stream->dep_next); +- +- link_sib(last_sib, dep_next); +- } else { +- link_dep(stream, dep_next); +- } +- +- for (si = dep_next; si; si = si->sib_next) { +- si->dep_prev = stream; +- if (si->queued) { +- rv = stream_obq_move(stream, dep_stream, si); +- if (rv != 0) { +- return rv; +- } +- } +- } +- } else { +- link_dep(dep_stream, stream); +- } +- +- if (stream_subtree_active(stream)) { +- rv = stream_obq_push(dep_stream, stream); +- if (rv != 0) { +- return rv; +- } +- } +- +- validate_tree(dep_stream); +- +- return 0; +-} +- +-int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, +- nghttp2_stream *stream) { +- int rv; +- +- DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n", +- dep_stream, dep_stream->stream_id, stream, stream->stream_id); +- +- dep_stream->sum_dep_weight += stream->weight; +- +- if (dep_stream->dep_next) { +- insert_link_dep(dep_stream, stream); +- } else { +- link_dep(dep_stream, stream); +- } +- +- if (stream_subtree_active(stream)) { +- rv = stream_obq_push(dep_stream, stream); +- if (rv != 0) { +- return rv; +- } +- } +- +- validate_tree(dep_stream); +- +- return 0; +-} +- +-void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) { +- nghttp2_stream *next, *dep_prev; +- +- DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream, +- stream->stream_id); +- +- assert(stream->dep_prev); +- +- dep_prev = stream->dep_prev; +- +- if (stream->sib_prev) { +- link_sib(stream->sib_prev, stream->sib_next); +- } else { +- next = stream->sib_next; +- +- link_dep(dep_prev, next); +- +- if (next) { +- next->sib_prev = NULL; +- } +- } +- +- dep_prev->sum_dep_weight -= stream->weight; +- +- if (stream->queued) { +- stream_obq_remove(stream); +- } +- +- validate_tree(dep_prev); +- +- stream->sib_prev = NULL; +- stream->sib_next = NULL; +- stream->dep_prev = NULL; +-} +- +-int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) { +- return stream->dep_prev || stream->dep_next || stream->sib_prev || +- stream->sib_next; +-} +- +-nghttp2_outbound_item * +-nghttp2_stream_next_outbound_item(nghttp2_stream *stream) { +- nghttp2_pq_entry *ent; +- nghttp2_stream *si; +- +- for (;;) { +- if (stream_active(stream)) { +- /* Update ascendant's descendant_last_cycle here, so that we can +- assure that new stream is scheduled based on it. */ +- for (si = stream; si->dep_prev; si = si->dep_prev) { +- si->dep_prev->descendant_last_cycle = si->cycle; +- } +- return stream->item; +- } +- ent = nghttp2_pq_top(&stream->obq); +- if (!ent) { +- return NULL; +- } +- stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry); ++nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) { ++ if (stream == &nghttp2_stream_root) { ++ return NGHTTP2_STREAM_STATE_IDLE; + } +-} + +-nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) { + if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) { + return NGHTTP2_STREAM_STATE_CLOSED; + } +@@ -988,27 +185,39 @@ nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) { + } + + nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) { +- return stream->dep_prev; ++ (void)stream; ++ ++ return NULL; + } + + nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) { +- return stream->sib_next; ++ (void)stream; ++ ++ return NULL; + } + + nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) { +- return stream->sib_prev; ++ (void)stream; ++ ++ return NULL; + } + + nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) { +- return stream->dep_next; ++ (void)stream; ++ ++ return NULL; + } + + int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) { +- return stream->weight; ++ (void)stream; ++ ++ return NGHTTP2_DEFAULT_WEIGHT; + } + + int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) { +- return stream->sum_dep_weight; ++ (void)stream; ++ ++ return 0; + } + + int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) { +diff --git a/deps/nghttp2/lib/nghttp2_stream.h b/deps/nghttp2/lib/nghttp2_stream.h +index 28add165..603209ec 100644 +--- a/deps/nghttp2/lib/nghttp2_stream.h ++++ b/deps/nghttp2/lib/nghttp2_stream.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + #include "nghttp2_outbound_item.h" +@@ -91,9 +91,6 @@ typedef enum { + /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and + NGHTTP2_STREAM_FLAG_DEFERRED_USER. */ + NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c, +- /* Indicates that this stream is not subject to RFC7540 +- priorities scheme. */ +- NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES = 0x10, + /* Ignore client RFC 9218 priority signal. */ + NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20, + /* Indicates that RFC 9113 leading and trailing white spaces +@@ -146,39 +143,18 @@ typedef enum { + } nghttp2_http_flag; + + struct nghttp2_stream { +- /* Entry for dep_prev->obq */ ++ nghttp2_stream_state state; + nghttp2_pq_entry pq_entry; +- /* Priority Queue storing direct descendant (nghttp2_stream). Only +- streams which itself has some data to send, or has a descendant +- which has some data to sent. */ +- nghttp2_pq obq; + /* Content-Length of request/response body. -1 if unknown. */ + int64_t content_length; + /* Received body so far */ + int64_t recv_content_length; +- /* Base last_cycle for direct descendent streams. */ +- uint64_t descendant_last_cycle; + /* Next scheduled time to sent item */ + uint64_t cycle; +- /* Next seq used for direct descendant streams */ +- uint64_t descendant_next_seq; + /* Secondary key for prioritization to break a tie for cycle. This + value is monotonically increased for single parent stream. */ + uint64_t seq; +- /* pointers to form dependency tree. If multiple streams depend on +- a stream, only one stream (left most) has non-NULL dep_prev which +- points to the stream it depends on. The remaining streams are +- linked using sib_prev and sib_next. The stream which has +- non-NULL dep_prev always NULL sib_prev. The right most stream +- has NULL sib_next. If this stream is a root of dependency tree, +- dep_prev and sib_prev are NULL. */ +- nghttp2_stream *dep_prev, *dep_next; +- nghttp2_stream *sib_prev, *sib_next; +- /* When stream is kept after closure, it may be kept in doubly +- linked list pointed by nghttp2_session closed_stream_head. +- closed_next points to the next stream object if it is the element +- of the list. */ +- nghttp2_stream *closed_prev, *closed_next; ++ nghttp2_stream *closed_next; + /* The arbitrary data provided by user for this stream. */ + void *stream_user_data; + /* Item to send */ +@@ -205,13 +181,8 @@ struct nghttp2_stream { + NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by + submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */ + int32_t local_window_size; +- /* weight of this stream */ +- int32_t weight; + /* This is unpaid penalty (offset) when calculating cycle. */ + uint32_t pending_penalty; +- /* sum of weight of direct descendants */ +- int32_t sum_dep_weight; +- nghttp2_stream_state state; + /* status code from remote server */ + int16_t status_code; + /* Bitwise OR of zero or more nghttp2_http_flag values */ +@@ -239,9 +210,9 @@ struct nghttp2_stream { + + void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, + uint8_t flags, nghttp2_stream_state initial_state, +- int32_t weight, int32_t remote_initial_window_size, ++ int32_t remote_initial_window_size, + int32_t local_initial_window_size, +- void *stream_user_data, nghttp2_mem *mem); ++ void *stream_user_data); + + void nghttp2_stream_free(nghttp2_stream *stream); + +@@ -267,14 +238,8 @@ void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags); + * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are + * cleared if they are set. So even if this function is called, if + * one of flag is still set, data does not become active. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory + */ +-int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags); ++void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags); + + /* + * Returns nonzero if item is deferred by whatever reason. +@@ -317,57 +282,11 @@ int nghttp2_stream_update_local_initial_window_size( + */ + void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream); + +-/* +- * Returns nonzero if |target| is an ancestor of |stream|. +- */ +-int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream, +- nghttp2_stream *target); +- +-/* +- * Computes distributed weight of a stream of the |weight| under the +- * |stream| if |stream| is removed from a dependency tree. +- */ +-int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream, +- int32_t weight); +- +-/* +- * Makes the |stream| depend on the |dep_stream|. This dependency is +- * exclusive. All existing direct descendants of |dep_stream| become +- * the descendants of the |stream|. This function assumes +- * |stream->item| is NULL. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream, +- nghttp2_stream *stream); +- +-/* +- * Makes the |stream| depend on the |dep_stream|. This dependency is +- * not exclusive. This function assumes |stream->item| is NULL. +- */ +-void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, nghttp2_stream *stream); +- +-/* +- * Removes the |stream| from the current dependency tree. This +- * function assumes |stream->item| is NULL. +- */ +-int nghttp2_stream_dep_remove(nghttp2_stream *stream); +- + /* + * Attaches |item| to |stream|. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory + */ +-int nghttp2_stream_attach_item(nghttp2_stream *stream, +- nghttp2_outbound_item *item); ++void nghttp2_stream_attach_item(nghttp2_stream *stream, ++ nghttp2_outbound_item *item); + + /* + * Detaches |stream->item|. This function does not free +@@ -375,66 +294,4 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream, + */ + void nghttp2_stream_detach_item(nghttp2_stream *stream); + +-/* +- * Makes the |stream| depend on the |dep_stream|. This dependency is +- * exclusive. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, +- nghttp2_stream *stream); +- +-/* +- * Makes the |stream| depend on the |dep_stream|. This dependency is +- * not exclusive. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, +- nghttp2_stream *stream); +- +-/* +- * Removes subtree whose root stream is |stream|. The +- * effective_weight of streams in removed subtree is not updated. +- * +- * This function returns 0 if it succeeds, or one of the following +- * negative error codes: +- * +- * NGHTTP2_ERR_NOMEM +- * Out of memory +- */ +-void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream); +- +-/* +- * Returns nonzero if |stream| is in any dependency tree. +- */ +-int nghttp2_stream_in_dep_tree(nghttp2_stream *stream); +- +-/* +- * Schedules transmission of |stream|'s item, assuming stream->item is +- * attached, and stream->last_writelen was updated. +- */ +-void nghttp2_stream_reschedule(nghttp2_stream *stream); +- +-/* +- * Changes |stream|'s weight to |weight|. If |stream| is queued, it +- * will be rescheduled based on new weight. +- */ +-void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight); +- +-/* +- * Returns a stream which has highest priority, updating +- * descendant_last_cycle of selected stream's ancestors. +- */ +-nghttp2_outbound_item * +-nghttp2_stream_next_outbound_item(nghttp2_stream *stream); +- +-#endif /* NGHTTP2_STREAM */ ++#endif /* !defined(NGHTTP2_STREAM_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_submit.c b/deps/nghttp2/lib/nghttp2_submit.c +index 81c1ab70..8a90f714 100644 +--- a/deps/nghttp2/lib/nghttp2_submit.c ++++ b/deps/nghttp2/lib/nghttp2_submit.c +@@ -32,42 +32,12 @@ + #include "nghttp2_helper.h" + #include "nghttp2_priority_spec.h" + +-/* +- * Detects the dependency error, that is stream attempted to depend on +- * itself. If |stream_id| is -1, we use session->next_stream_id as +- * stream ID. +- * +- * This function returns 0 if it succeeds, or one of the following +- * error codes: +- * +- * NGHTTP2_ERR_INVALID_ARGUMENT +- * Stream attempted to depend on itself. +- */ +-static int detect_self_dependency(nghttp2_session *session, int32_t stream_id, +- const nghttp2_priority_spec *pri_spec) { +- assert(pri_spec); +- +- if (stream_id == -1) { +- if ((int32_t)session->next_stream_id == pri_spec->stream_id) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- return 0; +- } +- +- if (stream_id == pri_spec->stream_id) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- return 0; +-} +- + /* This function takes ownership of |nva_copy|. Regardless of the + return value, the caller must not free |nva_copy| after this + function returns. */ + static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags, +- int32_t stream_id, +- const nghttp2_priority_spec *pri_spec, +- nghttp2_nv *nva_copy, size_t nvlen, ++ int32_t stream_id, nghttp2_nv *nva_copy, ++ size_t nvlen, + const nghttp2_data_provider_wrap *dpw, + void *stream_user_data) { + int rv; +@@ -114,8 +84,8 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags, + + frame = &item->frame; + +- nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, +- pri_spec, nva_copy, nvlen); ++ nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL, ++ nva_copy, nvlen); + + rv = nghttp2_session_add_item(session, item); + +@@ -141,31 +111,22 @@ fail2: + + static int32_t submit_headers_shared_nva(nghttp2_session *session, + uint8_t flags, int32_t stream_id, +- const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider_wrap *dpw, + void *stream_user_data) { + int rv; + nghttp2_nv *nva_copy; +- nghttp2_priority_spec copy_pri_spec; + nghttp2_mem *mem; + + mem = &session->mem; + +- if (pri_spec) { +- copy_pri_spec = *pri_spec; +- nghttp2_priority_spec_normalize_weight(©_pri_spec); +- } else { +- nghttp2_priority_spec_default_init(©_pri_spec); +- } +- + rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem); + if (rv < 0) { + return rv; + } + +- return submit_headers_shared(session, flags, stream_id, ©_pri_spec, +- nva_copy, nvlen, dpw, stream_user_data); ++ return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw, ++ stream_user_data); + } + + int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, +@@ -174,8 +135,8 @@ int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + +- return (int)submit_headers_shared_nva( +- session, NGHTTP2_FLAG_END_STREAM, stream_id, NULL, nva, nvlen, NULL, NULL); ++ return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM, ++ stream_id, nva, nvlen, NULL, NULL); + } + + int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, +@@ -183,7 +144,7 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, + const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, + void *stream_user_data) { +- int rv; ++ (void)pri_spec; + + if (stream_id == -1) { + if (session->server) { +@@ -195,20 +156,8 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, + + flags &= NGHTTP2_FLAG_END_STREAM; + +- if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) && +- session->remote_settings.no_rfc7540_priorities != 1) { +- rv = detect_self_dependency(session, stream_id, pri_spec); +- if (rv != 0) { +- return rv; +- } +- +- flags |= NGHTTP2_FLAG_PRIORITY; +- } else { +- pri_spec = NULL; +- } +- +- return submit_headers_shared_nva(session, flags, stream_id, pri_spec, nva, +- nvlen, NULL, stream_user_data); ++ return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL, ++ stream_user_data); + } + + int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, +@@ -220,51 +169,10 @@ int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, + int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_priority_spec *pri_spec) { +- int rv; +- nghttp2_outbound_item *item; +- nghttp2_frame *frame; +- nghttp2_priority_spec copy_pri_spec; +- nghttp2_mem *mem; ++ (void)session; + (void)flags; +- +- mem = &session->mem; +- +- if (session->remote_settings.no_rfc7540_priorities == 1) { +- return 0; +- } +- +- if (stream_id == 0 || pri_spec == NULL) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- if (stream_id == pri_spec->stream_id) { +- return NGHTTP2_ERR_INVALID_ARGUMENT; +- } +- +- copy_pri_spec = *pri_spec; +- +- nghttp2_priority_spec_normalize_weight(©_pri_spec); +- +- item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); +- +- if (item == NULL) { +- return NGHTTP2_ERR_NOMEM; +- } +- +- nghttp2_outbound_item_init(item); +- +- frame = &item->frame; +- +- nghttp2_frame_priority_init(&frame->priority, stream_id, ©_pri_spec); +- +- rv = nghttp2_session_add_item(session, item); +- +- if (rv != 0) { +- nghttp2_frame_priority_free(&frame->priority); +- nghttp2_mem_free(mem, item); +- +- return rv; +- } ++ (void)stream_id; ++ (void)pri_spec; + + return 0; + } +@@ -277,7 +185,8 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags, + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + +- return nghttp2_session_add_rst_stream(session, stream_id, error_code); ++ return nghttp2_session_add_rst_stream_continue( ++ session, stream_id, error_code, /* continue_without_stream = */ 0); + } + + int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags, +@@ -578,7 +487,7 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags, + return 0; + + fail_item_malloc: +- free(buf); ++ nghttp2_mem_free(mem, buf); + + return rv; + } +@@ -661,7 +570,7 @@ int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags, + return 0; + + fail_item_malloc: +- free(ov_copy); ++ nghttp2_mem_free(mem, ov_copy); + + return rv; + } +@@ -733,51 +642,34 @@ int nghttp2_submit_priority_update(nghttp2_session *session, uint8_t flags, + return 0; + + fail_item_malloc: +- free(buf); ++ nghttp2_mem_free(mem, buf); + + return rv; + } + +-static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec, +- const nghttp2_data_provider_wrap *dpw) { ++static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) { + uint8_t flags = NGHTTP2_FLAG_NONE; + if (dpw == NULL || dpw->data_prd.read_callback == NULL) { + flags |= NGHTTP2_FLAG_END_STREAM; + } + +- if (pri_spec) { +- flags |= NGHTTP2_FLAG_PRIORITY; +- } +- + return flags; + } + + static int32_t submit_request_shared(nghttp2_session *session, +- const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider_wrap *dpw, + void *stream_user_data) { + uint8_t flags; +- int rv; + + if (session->server) { + return NGHTTP2_ERR_PROTO; + } + +- if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) && +- session->remote_settings.no_rfc7540_priorities != 1) { +- rv = detect_self_dependency(session, -1, pri_spec); +- if (rv != 0) { +- return rv; +- } +- } else { +- pri_spec = NULL; +- } +- +- flags = set_request_flags(pri_spec, dpw); ++ flags = set_request_flags(dpw); + +- return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen, +- dpw, stream_user_data); ++ return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw, ++ stream_user_data); + } + + int32_t nghttp2_submit_request(nghttp2_session *session, +@@ -786,8 +678,9 @@ int32_t nghttp2_submit_request(nghttp2_session *session, + const nghttp2_data_provider *data_prd, + void *stream_user_data) { + nghttp2_data_provider_wrap dpw; ++ (void)pri_spec; + +- return submit_request_shared(session, pri_spec, nva, nvlen, ++ return submit_request_shared(session, nva, nvlen, + nghttp2_data_provider_wrap_v1(&dpw, data_prd), + stream_user_data); + } +@@ -798,8 +691,9 @@ int32_t nghttp2_submit_request2(nghttp2_session *session, + const nghttp2_data_provider2 *data_prd, + void *stream_user_data) { + nghttp2_data_provider_wrap dpw; ++ (void)pri_spec; + +- return submit_request_shared(session, pri_spec, nva, nvlen, ++ return submit_request_shared(session, nva, nvlen, + nghttp2_data_provider_wrap_v2(&dpw, data_prd), + stream_user_data); + } +@@ -826,8 +720,8 @@ static int submit_response_shared(nghttp2_session *session, int32_t stream_id, + } + + flags = set_response_flags(dpw); +- return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen, +- dpw, NULL); ++ return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw, ++ NULL); + } + + int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, +diff --git a/deps/nghttp2/lib/nghttp2_submit.h b/deps/nghttp2/lib/nghttp2_submit.h +index 350ee022..decf803d 100644 +--- a/deps/nghttp2/lib/nghttp2_submit.h ++++ b/deps/nghttp2/lib/nghttp2_submit.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -37,4 +37,4 @@ int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider_wrap *dpw); + +-#endif /* NGHTTP2_SUBMIT_H */ ++#endif /* !defined(NGHTTP2_SUBMIT_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_time.c b/deps/nghttp2/lib/nghttp2_time.c +index 148ccfdc..18fd7bca 100644 +--- a/deps/nghttp2/lib/nghttp2_time.c ++++ b/deps/nghttp2/lib/nghttp2_time.c +@@ -26,7 +26,7 @@ + + #ifdef HAVE_WINDOWS_H + # include +-#endif /* HAVE_WINDOWS_H */ ++#endif /* defined(HAVE_WINDOWS_H) */ + + #include + +@@ -40,12 +40,11 @@ static uint64_t time_now_sec(void) { + + return (uint64_t)t; + } +-#endif /* !HAVE_GETTICKCOUNT64 || __CYGWIN__ */ ++#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */ + + #if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__) + uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } +-#elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \ +- HAVE_DECL_CLOCK_MONOTONIC ++#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC + uint64_t nghttp2_time_now_sec(void) { + struct timespec tp; + int rv = clock_gettime(CLOCK_MONOTONIC, &tp); +@@ -56,8 +55,8 @@ uint64_t nghttp2_time_now_sec(void) { + + return (uint64_t)tp.tv_sec; + } +-#else /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \ +- (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */ ++#else /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \ ++ (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */ + uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } +-#endif /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \ +- (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */ ++#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \ ++ (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */ +diff --git a/deps/nghttp2/lib/nghttp2_time.h b/deps/nghttp2/lib/nghttp2_time.h +index 03c0bbe9..a91e62ad 100644 +--- a/deps/nghttp2/lib/nghttp2_time.h ++++ b/deps/nghttp2/lib/nghttp2_time.h +@@ -27,7 +27,7 @@ + + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +@@ -35,4 +35,4 @@ + timepoint. If it is unable to get seconds, it returns 0. */ + uint64_t nghttp2_time_now_sec(void); + +-#endif /* NGHTTP2_TIME_H */ ++#endif /* !defined(NGHTTP2_TIME_H) */ +diff --git a/deps/nghttp2/lib/nghttp2_version.c b/deps/nghttp2/lib/nghttp2_version.c +index 4211f2cf..39a49ff3 100644 +--- a/deps/nghttp2/lib/nghttp2_version.c ++++ b/deps/nghttp2/lib/nghttp2_version.c +@@ -24,7 +24,7 @@ + */ + #ifdef HAVE_CONFIG_H + # include +-#endif /* HAVE_CONFIG_H */ ++#endif /* defined(HAVE_CONFIG_H) */ + + #include + +diff --git a/deps/nghttp2/lib/sfparse.c b/deps/nghttp2/lib/sfparse.c +index b5e94cc2..cee089d3 100644 +--- a/deps/nghttp2/lib/sfparse.c ++++ b/deps/nghttp2/lib/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': \ +@@ -135,6 +143,70 @@ + UCALPHA_CASES: \ + LCALPHA_CASES + ++#define TOKEN_CASES \ ++ case '!': \ ++ case '#': \ ++ case '$': \ ++ case '%': \ ++ case '&': \ ++ case '\'': \ ++ case '*': \ ++ case '+': \ ++ case '-': \ ++ case '.': \ ++ case '/': \ ++ DIGIT_CASES: \ ++ case ':': \ ++ UCALPHA_CASES: \ ++ case '^': \ ++ case '_': \ ++ case '`': \ ++ LCALPHA_CASES: \ ++ case '|': \ ++ case '~' ++ ++#define LCHEXALPHA_CASES \ ++ case 'a': \ ++ case 'b': \ ++ case 'c': \ ++ case 'd': \ ++ case 'e': \ ++ case 'f' ++ ++#define X00_1F_CASES \ ++ case 0x00: \ ++ case 0x01: \ ++ case 0x02: \ ++ case 0x03: \ ++ case 0x04: \ ++ case 0x05: \ ++ case 0x06: \ ++ case 0x07: \ ++ case 0x08: \ ++ case 0x09: \ ++ case 0x0a: \ ++ case 0x0b: \ ++ case 0x0c: \ ++ case 0x0d: \ ++ case 0x0e: \ ++ case 0x0f: \ ++ case 0x10: \ ++ case 0x11: \ ++ case 0x12: \ ++ case 0x13: \ ++ case 0x14: \ ++ case 0x15: \ ++ case 0x16: \ ++ case 0x17: \ ++ case 0x18: \ ++ case 0x19: \ ++ case 0x1a: \ ++ case 0x1b: \ ++ case 0x1c: \ ++ case 0x1d: \ ++ case 0x1e: \ ++ case 0x1f ++ + #define X20_21_CASES \ + case ' ': \ + case '!' +@@ -175,6 +247,137 @@ + case '}': \ + case '~' + ++#define X7F_FF_CASES \ ++ case 0x7f: \ ++ case 0x80: \ ++ case 0x81: \ ++ case 0x82: \ ++ case 0x83: \ ++ case 0x84: \ ++ case 0x85: \ ++ case 0x86: \ ++ case 0x87: \ ++ case 0x88: \ ++ case 0x89: \ ++ case 0x8a: \ ++ case 0x8b: \ ++ case 0x8c: \ ++ case 0x8d: \ ++ case 0x8e: \ ++ case 0x8f: \ ++ case 0x90: \ ++ case 0x91: \ ++ case 0x92: \ ++ case 0x93: \ ++ case 0x94: \ ++ case 0x95: \ ++ case 0x96: \ ++ case 0x97: \ ++ case 0x98: \ ++ case 0x99: \ ++ case 0x9a: \ ++ case 0x9b: \ ++ case 0x9c: \ ++ case 0x9d: \ ++ case 0x9e: \ ++ case 0x9f: \ ++ case 0xa0: \ ++ case 0xa1: \ ++ case 0xa2: \ ++ case 0xa3: \ ++ case 0xa4: \ ++ case 0xa5: \ ++ case 0xa6: \ ++ case 0xa7: \ ++ case 0xa8: \ ++ case 0xa9: \ ++ case 0xaa: \ ++ case 0xab: \ ++ case 0xac: \ ++ case 0xad: \ ++ case 0xae: \ ++ case 0xaf: \ ++ case 0xb0: \ ++ case 0xb1: \ ++ case 0xb2: \ ++ case 0xb3: \ ++ case 0xb4: \ ++ case 0xb5: \ ++ case 0xb6: \ ++ case 0xb7: \ ++ case 0xb8: \ ++ case 0xb9: \ ++ case 0xba: \ ++ case 0xbb: \ ++ case 0xbc: \ ++ case 0xbd: \ ++ case 0xbe: \ ++ case 0xbf: \ ++ case 0xc0: \ ++ case 0xc1: \ ++ case 0xc2: \ ++ case 0xc3: \ ++ case 0xc4: \ ++ case 0xc5: \ ++ case 0xc6: \ ++ case 0xc7: \ ++ case 0xc8: \ ++ case 0xc9: \ ++ case 0xca: \ ++ case 0xcb: \ ++ case 0xcc: \ ++ case 0xcd: \ ++ case 0xce: \ ++ case 0xcf: \ ++ case 0xd0: \ ++ case 0xd1: \ ++ case 0xd2: \ ++ case 0xd3: \ ++ case 0xd4: \ ++ case 0xd5: \ ++ case 0xd6: \ ++ case 0xd7: \ ++ case 0xd8: \ ++ case 0xd9: \ ++ case 0xda: \ ++ case 0xdb: \ ++ case 0xdc: \ ++ case 0xdd: \ ++ case 0xde: \ ++ case 0xdf: \ ++ case 0xe0: \ ++ case 0xe1: \ ++ case 0xe2: \ ++ case 0xe3: \ ++ case 0xe4: \ ++ case 0xe5: \ ++ case 0xe6: \ ++ case 0xe7: \ ++ case 0xe8: \ ++ case 0xe9: \ ++ case 0xea: \ ++ case 0xeb: \ ++ case 0xec: \ ++ case 0xed: \ ++ case 0xee: \ ++ case 0xef: \ ++ case 0xf0: \ ++ case 0xf1: \ ++ case 0xf2: \ ++ case 0xf3: \ ++ case 0xf4: \ ++ case 0xf5: \ ++ case 0xf6: \ ++ case 0xf7: \ ++ case 0xf8: \ ++ case 0xf9: \ ++ case 0xfa: \ ++ case 0xfb: \ ++ case 0xfc: \ ++ case 0xfd: \ ++ case 0xfe: \ ++ case 0xff ++ + static int is_ws(uint8_t c) { + switch (c) { + case ' ': +@@ -185,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 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(sf_parser *sfp) { ++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 '_': +@@ -233,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); +@@ -241,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; +@@ -250,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; +@@ -262,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; +@@ -275,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; + } + +@@ -291,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; +@@ -302,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; +@@ -315,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) { +@@ -342,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); +@@ -352,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); +@@ -360,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: +@@ -390,75 +730,131 @@ 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; +- } ++ goto fin; ++ default: ++ return SFPARSE_ERR_PARSE; ++ } ++ } + +- ++sfp->pos; ++ return SFPARSE_ERR_PARSE; + +- return 0; +- default: +- return SF_ERR_PARSE_ERROR; ++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; ++} ++ ++#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 SF_ERR_PARSE_ERROR; ++ return last; + } ++#endif /* __AVX2__ */ + +-static int parser_token(sf_parser *sfp, sf_value *dest) { ++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) { +- case '!': +- case '#': +- case '$': +- case '%': +- case '&': +- case '\'': +- case '*': +- case '+': +- case '-': +- case '.': +- case '^': +- case '_': +- case '`': +- case '|': +- case '~': +- case ':': +- case '/': +- DIGIT_CASES: +- ALPHA_CASES: ++ TOKEN_CASES: + continue; + } + + 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); + } +@@ -466,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 '+': +@@ -485,75 +930,47 @@ 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: +- 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; ++ if (parser_eof(sfp)) { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ if (*sfp->pos == '=') { ++ ++sfp->pos; + } + + 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; +- } ++ ++sfp->pos; + + break; + } + +- ++sfp->pos; +- + if (parser_eof(sfp) || *sfp->pos != ':') { +- return SF_ERR_PARSE_ERROR; ++ return SFPARSE_ERR_PARSE; + } + + goto fin; + case ':': +- if ((sfp->pos - base) & 0x3) { +- return SF_ERR_PARSE_ERROR; ++ if (((sfp->pos - base) & 0x3) == 1) { ++ 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; + } +@@ -563,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. */ +@@ -572,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) { +@@ -585,21 +1002,184 @@ 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; + } + + return 0; + } + +-static int parser_bare_item(sf_parser *sfp, sf_value *dest) { ++static int pctdecode(uint8_t *pc, const uint8_t **ppos) { ++ uint8_t c, b = **ppos; ++ ++ switch (b) { ++ DIGIT_CASES: ++ c = (uint8_t)((b - '0') << 4); ++ ++ break; ++ LCHEXALPHA_CASES: ++ c = (uint8_t)((b - 'a' + 10) << 4); ++ ++ break; ++ default: ++ return -1; ++ } ++ ++ b = *++*ppos; ++ ++ switch (b) { ++ DIGIT_CASES: ++ c |= (uint8_t)(b - '0'); ++ ++ break; ++ LCHEXALPHA_CASES: ++ c |= (uint8_t)(b - 'a' + 10); ++ ++ break; ++ default: ++ return -1; ++ } ++ ++ *pc = c; ++ ++*ppos; ++ ++ return 0; ++} ++ ++/* Start of utf8 dfa */ ++/* Copyright (c) 2008-2010 Bjoern Hoehrmann ++ * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. ++ * ++ * Copyright (c) 2008-2009 Bjoern Hoehrmann ++ * ++ * 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. ++ */ ++#define UTF8_ACCEPT 0 ++#define UTF8_REJECT 12 ++ ++/* clang-format off */ ++static const uint8_t utf8d[] = { ++ /* ++ * The first part of the table maps bytes to character classes that ++ * to reduce the size of the transition table and create bitmasks. ++ */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ++ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, ++ 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, ++ ++ /* ++ * The second part is a transition table that maps a combination ++ * of a state of the automaton and a character class to a state. ++ */ ++ 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, ++ 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, ++ 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, ++ 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, ++ 12,36,12,12,12,12,12,12,12,12,12,12, ++}; ++/* clang-format on */ ++ ++static void utf8_decode(uint32_t *state, uint8_t byte) { ++ *state = utf8d[256 + *state + utf8d[byte]]; ++} ++ ++/* End of utf8 dfa */ ++ ++static int parser_dispstring(sfparse_parser *sfp, sfparse_value *dest) { ++ const uint8_t *base; ++ uint8_t c; ++ uint32_t utf8state = UTF8_ACCEPT; ++ ++ assert('%' == *sfp->pos); ++ ++ ++sfp->pos; ++ ++ if (parser_eof(sfp) || *sfp->pos != '"') { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ base = ++sfp->pos; ++ ++ for (; !parser_eof(sfp);) { ++ switch (*sfp->pos) { ++ X00_1F_CASES: ++ X7F_FF_CASES: ++ return SFPARSE_ERR_PARSE; ++ case '%': ++ ++sfp->pos; ++ ++ if (sfp->pos + 2 > sfp->end) { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ if (pctdecode(&c, &sfp->pos) != 0) { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ utf8_decode(&utf8state, c); ++ if (utf8state == UTF8_REJECT) { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ break; ++ case '"': ++ if (utf8state != UTF8_ACCEPT) { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ if (dest) { ++ 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; ++ } ++ ++ ++sfp->pos; ++ ++ return 0; ++ default: ++ if (utf8state != UTF8_ACCEPT) { ++ return SFPARSE_ERR_PARSE; ++ } ++ ++ ++sfp->pos; ++ } ++ } ++ ++ return SFPARSE_ERR_PARSE; ++} ++ ++static int parser_bare_item(sfparse_parser *sfp, sfparse_value *dest) { + switch (*sfp->pos) { + case '"': + return parser_string(sfp, dest); +@@ -615,29 +1195,32 @@ static int parser_bare_item(sf_parser *sfp, sf_value *dest) { + case '*': + ALPHA_CASES: + return parser_token(sfp, 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); +@@ -645,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); +@@ -664,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; + } + +@@ -675,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); +@@ -700,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; +@@ -751,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); +@@ -761,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); +@@ -785,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; + } +@@ -825,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; + } +@@ -846,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; +@@ -897,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; +@@ -937,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; + } +@@ -953,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(); +@@ -999,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; + } +@@ -1015,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 { +@@ -1028,16 +1613,16 @@ 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; + + if (src->len == 0) { +- *dest = *src; ++ dest->len = 0; + + return; + } +@@ -1049,16 +1634,12 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) { + for (;;) { + q = memchr(p, '\\', len); + if (q == NULL) { +- if (len == src->len) { +- *dest = *src; +- +- return; +- } +- + memcpy(o, p, len); + o += len; + +- break; ++ dest->len = (size_t)(o - dest->base); ++ ++ return; + } + + slen = (size_t)(q - p); +@@ -1069,11 +1650,9 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) { + *o++ = *p++; + len -= slen + 2; + } +- +- dest->len = (size_t)(o - dest->base); + } + +-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, +@@ -1092,20 +1671,22 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) { + uint8_t *o; + const uint8_t *p, *end; + uint32_t n; +- size_t i; ++ size_t i, left; + int idx; + +- assert((src->len & 0x3) == 0); +- + if (src->len == 0) { +- *dest = *src; ++ dest->len = 0; + + return; + } + + o = dest->base; + p = src->base; +- end = src->base + src->len; ++ left = src->len & 0x3; ++ if (left == 0 && src->base[src->len - 1] == '=') { ++ left = 4; ++ } ++ end = src->base + src->len - left; + + for (; p != end;) { + n = 0; +@@ -1113,33 +1694,94 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) { + for (i = 1; i <= 4; ++i, ++p) { + idx = index_tbl[*p]; + +- if (idx == -1) { +- assert(i > 2); ++ assert(idx != -1); + +- if (i == 3) { +- assert(*p == '=' && *(p + 1) == '=' && p + 2 == end); ++ n += (uint32_t)(idx << (24 - i * 6)); ++ } + +- *o++ = (uint8_t)(n >> 16); ++ *o++ = (uint8_t)(n >> 16); ++ *o++ = (n >> 8) & 0xffu; ++ *o++ = n & 0xffu; ++ } + +- goto fin; +- } ++ switch (left) { ++ case 0: ++ goto fin; ++ case 1: ++ assert(0); ++ abort(); ++ case 3: ++ if (src->base[src->len - 1] == '=') { ++ left = 2; ++ } + +- assert(*p == '=' && p + 1 == end); ++ break; ++ case 4: ++ assert('=' == src->base[src->len - 1]); + +- *o++ = (uint8_t)(n >> 16); +- *o++ = (n >> 8) & 0xffu; ++ if (src->base[src->len - 2] == '=') { ++ left = 2; ++ } else { ++ left = 3; ++ } + +- goto fin; +- } ++ break; ++ } + +- n += (uint32_t)(idx << (24 - i * 6)); +- } ++ switch (left) { ++ case 2: ++ *o = (uint8_t)(index_tbl[*p++] << 2); ++ *o++ |= (uint8_t)(index_tbl[*p++] >> 4); + +- *o++ = (uint8_t)(n >> 16); ++ break; ++ case 3: ++ n = (uint32_t)(index_tbl[*p++] << 10); ++ n += (uint32_t)(index_tbl[*p++] << 4); ++ n += (uint32_t)(index_tbl[*p++] >> 2); + *o++ = (n >> 8) & 0xffu; + *o++ = n & 0xffu; ++ ++ break; + } + + fin: + dest->len = (size_t)(o - dest->base); + } ++ ++void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src) { ++ const uint8_t *p, *q; ++ uint8_t *o; ++ size_t len, slen; ++ ++ if (src->len == 0) { ++ dest->len = 0; ++ ++ return; ++ } ++ ++ o = dest->base; ++ p = src->base; ++ len = src->len; ++ ++ for (;;) { ++ q = memchr(p, '%', len); ++ if (q == NULL) { ++ memcpy(o, p, len); ++ o += len; ++ ++ dest->len = (size_t)(o - dest->base); ++ ++ return; ++ } ++ ++ slen = (size_t)(q - p); ++ memcpy(o, p, slen); ++ o += slen; ++ ++ p = q + 1; ++ ++ pctdecode(o++, &p); ++ ++ len -= slen + 3; ++ } ++} +diff --git a/deps/nghttp2/lib/sfparse.h b/deps/nghttp2/lib/sfparse.h +index 1474db14..9341221a 100644 +--- a/deps/nghttp2/lib/sfparse.h ++++ b/deps/nghttp2/lib/sfparse.h +@@ -31,86 +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 +-} sf_type; ++ SFPARSE_TYPE_DATE, ++ /** ++ * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string 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. + */ +@@ -119,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. + */ +@@ -150,260 +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`, or +- * :enum:`sf_type.SF_TYPE_BYTESEQ`. ++ * 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`. + * +- * If :member:`vec.len ` == 0, :member:`vec.base +- * ` is guaranteed to be NULL. ++ * 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. + */ +- 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. +- * +- * If there is no escape character in |src|, |*src| is assigned to +- * |*dest|. This includes the case that :member:`src->len +- * ` == 0. ++ * :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 +- * 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. ++ * `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. + * +- * :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:`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. + * +- * If :member:`src->len ` == 0, |*src| is assigned to +- * |*dest|. ++ * :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); ++void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src); + + #ifdef __cplusplus + } +-#endif ++#endif /* defined(__cplusplus) */ + +-#endif /* SFPARSE_H */ ++#endif /* !defined(SFPARSE_H) */ +-- +2.53.0 + diff --git a/0001-fips-disable-options.patch b/0001-fips-disable-options.patch new file mode 100644 index 0000000..56482a2 --- /dev/null +++ b/0001-fips-disable-options.patch @@ -0,0 +1,84 @@ +From 98738d27288bd9ca634e29181ef665e812e7bbd3 Mon Sep 17 00:00:00 2001 +From: Michael Dawson +Date: Fri, 23 Feb 2024 13:43:56 +0100 +Subject: [PATCH] Disable FIPS options + +On RHEL, FIPS should be configured only on system level. +Additionally, the related options may cause segfault when used on RHEL. + +This patch causes the option processing to end sooner +than the problematic code gets executed. +Additionally, the JS-level options to mess with FIPS settings +are similarly disabled. + +Upstream report: https://github.com/nodejs/node/pull/48950 +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=2226726 +--- + lib/crypto.js | 10 ++++++++++ + lib/internal/errors.js | 6 ++++++ + src/crypto/crypto_util.cc | 2 ++ + 3 files changed, 18 insertions(+) + +diff --git a/lib/crypto.js b/lib/crypto.js +index 41adecc..b2627ac 100644 +--- a/lib/crypto.js ++++ b/lib/crypto.js +@@ -36,7 +36,10 @@ const { + assertCrypto(); + + const { ++ // RHEL specific error ++ ERR_CRYPTO_FIPS_SYSTEM_CONTROLLED, ++ + ERR_CRYPTO_FIPS_FORCED, + ERR_WORKER_UNSUPPORTED_OPERATION, + } = require('internal/errors').codes; + const constants = internalBinding('constants').crypto; +@@ -251,6 +254,13 @@ function getFips() { + } + + function setFips(val) { ++ // in RHEL FIPS enable/disable should only be done at system level ++ if (getFips() != val) { ++ throw new ERR_CRYPTO_FIPS_SYSTEM_CONTROLLED(); ++ } else { ++ return; ++ } ++ + if (getOptionValue('--force-fips')) { + if (val) return; + throw new ERR_CRYPTO_FIPS_FORCED(); +diff --git a/lib/internal/errors.js b/lib/internal/errors.js +index a722360..04d8a53 100644 +--- a/lib/internal/errors.js ++++ b/lib/internal/errors.js +@@ -1111,6 +1111,12 @@ module.exports = { + // + // Note: Node.js specific errors must begin with the prefix ERR_ + ++// insert RHEL specific erro ++E('ERR_CRYPTO_FIPS_SYSTEM_CONTROLLED', ++ 'Cannot set FIPS mode. FIPS should be enabled/disabled at system level. See' + ++ 'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/assembly_installing-the-system-in-fips-mode_security-hardening for more details.\n', ++ Error); ++ + E('ERR_ACCESS_DENIED', + function(msg, permission = '', resource = '') { + this.permission = permission; +diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc +index 5734d8f..ef9d1b1 100644 +--- a/src/crypto/crypto_util.cc ++++ b/src/crypto/crypto_util.cc +@@ -121,6 +121,8 @@ bool ProcessFipsOptions() { + /* Override FIPS settings in configuration file, if needed. */ + if (per_process::cli_options->enable_fips_crypto || + per_process::cli_options->force_fips_crypto) { ++ fprintf(stderr, "ERROR: Using options related to FIPS is not recommended, configure FIPS in openssl instead. See https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/assembly_installing-the-system-in-fips-mode_security-hardening for more details.\n"); ++ return false; + #if OPENSSL_VERSION_MAJOR >= 3 + OSSL_PROVIDER* fips_provider = OSSL_PROVIDER_load(nullptr, "fips"); + if (fips_provider == nullptr) +-- +2.43.2 + + diff --git a/nodejs-tarball.sh b/nodejs-tarball.sh index a908c63..ca1dcd8 100755 --- a/nodejs-tarball.sh +++ b/nodejs-tarball.sh @@ -108,7 +108,7 @@ echo $_arg_version if [ x$_arg_version != x ]; then version=$_arg_version else - version=$(rpm -q --specfile --qf='%{version}\n' nodejs.spec | head -n1) + version=$(rpm -q --specfile --qf='%{version}\n' nodejs*.spec | head -n1) fi rm -f node-v${version}.tar.gz node-v${version}-stripped.tar.gz @@ -120,11 +120,11 @@ rm -rf node-v${version}/deps/openssl tar -zcf node-v${version}-stripped.tar.gz node-v${version} # Download the ICU binary data files -ICU_MAJOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\)-\([[:digit:]]\+\).*/\1/g') -ICU_MINOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\)-\([[:digit:]]\+\).*/\2/g') -rm -Rf icu4c-${ICU_MAJOR}_${ICU_MINOR}-data-bin-*.zip -wget $(grep Source3 nodejs.spec | sed --expression="s/.*http/http/g" --expression="s/\(\%{icu_major}\)/${ICU_MAJOR}/g" --expression="s/\(\%{icu_minor}\)/${ICU_MINOR}/g") -wget $(grep Source4 nodejs.spec | sed --expression="s/.*http/http/g" --expression="s/\(\%{icu_major}\)/${ICU_MAJOR}/g" --expression="s/\(\%{icu_minor}\)/${ICU_MINOR}/g") +ICU_MAJOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\).\([[:digit:]]\+\).*/\1/g') +ICU_MINOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\).\([[:digit:]]\+\).*/\2/g') +rm -Rf icu4c-${ICU_MAJOR}.${ICU_MINOR}-data-bin-*.zip +wget $(grep -w 'Source3' nodejs22.spec | sed --expression="s/.*http/http/g" --expression="s/\(\%{icu_major}\)/${ICU_MAJOR}/g" --expression="s/\(\%{icu_minor}\)/${ICU_MINOR}/g") +wget $(grep -w 'Source4' nodejs22.spec | sed --expression="s/.*http/http/g" --expression="s/\(\%{icu_major}\)/${ICU_MAJOR}/g" --expression="s/\(\%{icu_minor}\)/${ICU_MINOR}/g") #fedpkg new-sources node-v${version}-stripped.tar.gz icu4c*-src.tgz @@ -194,8 +194,8 @@ echo $NGTCP2_VERSION echo echo "ICU" echo "=========================" -ICU_MAJOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\)-\([[:digit:]]\+\).*/\1/g') -ICU_MINOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\)-\([[:digit:]]\+\).*/\2/g') +ICU_MAJOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\).\([[:digit:]]\+\).*/\1/g') +ICU_MINOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\).\([[:digit:]]\+\).*/\2/g') echo "${ICU_MAJOR}.${ICU_MINOR}" echo echo "simdutf" diff --git a/nodejs22.spec b/nodejs22.spec index 0a79dda..738db44 100644 --- a/nodejs22.spec +++ b/nodejs22.spec @@ -2,7 +2,7 @@ ## (rpmautospec version 0.6.5) ## RPMAUTOSPEC: autorelease, autochangelog %define autorelease(e:s:pb:n) %{?-p:0.}%{lua: - release_number = 4; + release_number = 1; base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}")); print(release_number + base_release_number - 1); }%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}} @@ -12,6 +12,10 @@ # The default version will own /usr/bin/node and friends %global nodejs_pkg_major 22 +%if 0%{?fedora} == 41 || 0%{?fedora} == 42 || 0%{?rhel} == 10 +%global nodejs_default %{nodejs_pkg_major} +%endif + %global nodejs_default_sitelib %{_prefix}/lib/node_modules %global nodejs_private_sitelib %{nodejs_default_sitelib}_%{nodejs_pkg_major} @@ -58,8 +62,8 @@ # than a Fedora release lifecycle. %global nodejs_epoch 1 %global nodejs_major 22 -%global nodejs_minor 13 -%global nodejs_patch 1 +%global nodejs_minor 22 +%global nodejs_patch 2 # nodejs_soversion - from NODE_MODULE_VERSION in src/node_version.h %global nodejs_soversion 127 %global nodejs_abi %{nodejs_soversion} @@ -86,26 +90,26 @@ # c-ares - from deps/cares/include/ares_version.h # https://github.com/nodejs/node/pull/9332 -%global c_ares_version 1.34.4 +%global c_ares_version 1.34.6 # llhttp - from deps/llhttp/include/llhttp.h -%global llhttp_version 9.2.1 +%global llhttp_version 9.3.0 # libuv - from deps/uv/include/uv/version.h -%global libuv_version 1.49.2 +%global libuv_version 1.51.0 # nghttp2 - from deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h -%global nghttp2_version 1.64.0 +%global nghttp2_version 1.68.1 # nghttp3 - from deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h %global nghttp3_version 1.6.0 # ngtcp2 from deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h -%global ngtcp2_version 1.9.1 +%global ngtcp2_version 1.11.0 # ICU - from tools/icu/current_ver.dep -%global icu_major 76 -%global icu_minor 1 +%global icu_major 78 +%global icu_minor 2 %global icu_version %{icu_major}.%{icu_minor} %global icudatadir %{nodejs_datadir}/icudata @@ -113,7 +117,7 @@ # " this line just fixes syntax highlighting for vim that is confused by the above and continues literal # simdutf from deps/simdutf/simdutf.h -%global simdutf_version 5.6.4 +%global simdutf_version 6.4.2 # OpenSSL minimum version %global openssl11_minimum 1:1.1.1 @@ -126,7 +130,7 @@ # npm - from deps/npm/package.json %global npm_epoch 1 -%global npm_version 10.9.2 +%global npm_version 10.9.7 # In order to avoid needing to keep incrementing the release version for the # main package forever, we will just construct one for npm that is guaranteed @@ -137,13 +141,13 @@ %global npm_envr %{npm_epoch}:%{npm_version}-%{npm_release} # uvwasi - from deps/uvwasi/include/uvwasi.h -%global uvwasi_version 0.0.21 +%global uvwasi_version 0.0.23 # histogram_c - assumed from timestamps -%global histogram_version 0.9.7 +%global histogram_version 0.11.9 # sqlite – from deps/sqlite/sqlite3.h -%global sqlite_version 3.47.2 +%global sqlite_version 3.51.2 Name: nodejs%{nodejs_pkg_major} @@ -165,16 +169,21 @@ Source0: node-v%{nodejs_version}-stripped.tar.gz Source1: npmrc Source2: btest402.js # The binary data that icu-small can use to get icu-full capability -Source3: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-b.zip -Source4: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-l.zip +Source3: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}.%{icu_minor}/icu4c-%{icu_major}.%{icu_minor}-data-bin-b.zip +Source4: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}.%{icu_minor}/icu4c-%{icu_major}.%{icu_minor}-data-bin-l.zip Source200: nodejs-tarball.sh Source201: npmrc.builtin.in Source202: nodejs.pc.in Source203: v8.pc.in Source204: nodejs22_abi.req Source205: nodejs22_abi.attr +Source300: test-runner.sh +Source301: test-should-pass.txt Patch: 0001-Remove-unused-OpenSSL-config.patch +Patch: 0001-fips-disable-options.patch +Patch: 0001-deps-update-nghttp2-to-1.68.1.patch +Patch: 0001-CVE-2026-25547-braces-expansion.patch %if 0%{?nodejs_default} %global pkgname nodejs @@ -228,14 +237,19 @@ BuildRequires: pkgconfig(sqlite3) >= 3.45.0 %if 0%{?nodejs_default} Provides: nodejs = %{nodejs_envr} -%endif - -# RHEL-10: obsolete packages with the unversioned names; -# we do not want a default stream at all. -# The default version is set to the last version shipped in default stream -%define obsolete_default_stream_package() %{expand:\ -Obsoletes: nodejs%{?1:-%{1}} < %{?2}%{!?2:22.13.1-2} +# To keep the upgrade path clean, we Obsolete nodejsXX from the nodejs +# package and nodejsXX-foo from individual subpackages. +# Note that using Obsoletes without package version is not standard practice. +# Here we assert that *any* version of the system's default interpreter is +# preferable to an "extra" interpreter. For example, nodejs-20.5.0 will +# replace nodejs20-20.6.0. +%define unversioned_obsoletes_of_nodejsXX_if_default() %{expand:\ +Obsoletes: nodejs%{nodejs_pkg_major}%{?1:-%{1}} < %{nodejs_envr}\ +Provides: nodejs%{nodejs_pkg_major}%{?1:-%{1}} = %{nodejs_envr}\ } +%else +%define unversioned_obsoletes_of_nodejsXX_if_default() %{nil} +%endif %if %{with bundled} Provides: bundled(libuv) = %{libuv_version} @@ -346,21 +360,21 @@ Provides: bundled(ada) = 2.9.2 # undici and cjs-module-lexer ship with pre-built WASM binaries. %if %{with bundled_cjs_module_lexer} -Provides: bundled(nodejs-cjs-module-lexer) = 1.4.1 +Provides: bundled(nodejs-cjs-module-lexer) = 2.2.0 %else BuildRequires: nodejs-cjs-module-lexer Requires: nodejs-cjs-module-lexer %endif %if %{with bundled_undici} -Provides: bundled(nodejs-undici) = 6.21.1 +Provides: bundled(nodejs-undici) = 6.24.1 %else BuildRequires: nodejs-undici Requires: nodejs-undici %endif -%obsolete_default_stream_package +%unversioned_obsoletes_of_nodejsXX_if_default %description @@ -371,6 +385,16 @@ makes it lightweight and efficient, perfect for data-intensive \ real-time applications that run across distributed devices.} +%if 0%{?nodejs_default} +%description -n %{pkgname} +Node.js is a platform built on Chrome's JavaScript runtime \ +for easily building fast, scalable network applications. \ +Node.js uses an event-driven, non-blocking I/O model that \ +makes it lightweight and efficient, perfect for data-intensive \ +real-time applications that run across distributed devices.} +%endif + + %package -n %{pkgname}-devel Summary: JavaScript runtime - development headers Group: Development/Languages @@ -390,10 +414,12 @@ Requires: libuv-devel%{?_isa} %if 0%{?nodejs_default} Provides: nodejs-devel = %{nodejs_envr} %endif -%obsolete_default_stream_package devel +%unversioned_obsoletes_of_nodejsXX_if_default devel -Provides: nodejs-devel-pkg = %{nodejs_envr} +Provides: alternative-for(nodejs-devel) = %{nodejs_envr} +Conflicts: alternative-for(nodejs-devel) Conflicts: nodejs-devel-pkg + # previously VP used for the same reason as alternative-for() above %description -n %{pkgname}-devel @@ -420,7 +446,7 @@ Provides: v8%{?_isa} = %{v8_epoch}:%{v8_version}-%{nodejs_release} Obsoletes: v8 < 1:6.7.17-10 Provides: nodejs-libs = %{nodejs_envr} -%obsolete_default_stream_package libs +%unversioned_obsoletes_of_nodejsXX_if_default libs %description -n %{pkgname}-libs Libraries to support Node.js and provide stable v8 interfaces. @@ -430,7 +456,7 @@ Libraries to support Node.js and provide stable v8 interfaces. Summary: Non-English locale data for Node.js Requires: %{pkgname}%{?_isa} = %{nodejs_envr} -%obsolete_default_stream_package full-i18n +%unversioned_obsoletes_of_nodejsXX_if_default full-i18n %description -n %{pkgname}-full-i18n @@ -479,10 +505,12 @@ Provides: npm = %{npm_envr} # Obsolete the old 'npm' package Obsoletes: npm < 1:9 -%endif -# Obsolete latest version of default stream package. -%obsolete_default_stream_package npm 10.9.2-1.22.13.1.2 +# Obsolete others. We can't use %%unversioned_obsoletes_of_nodejsXX_if_default +# here because the Provides: needs its own version +Obsoletes: nodejs%{nodejs_pkg_major}-npm < %{npm_envr} +Provides: nodejs%{nodejs_pkg_major}-npm = %{npm_envr} +%endif %description -n %{pkgname}-npm @@ -497,7 +525,7 @@ BuildArch: noarch Requires(meta): %{pkgname} = %{nodejs_envr} Provides: nodejs-docs = %{nodejs_envr} -%obsolete_default_stream_package docs +%unversioned_obsoletes_of_nodejsXX_if_default docs %description -n %{pkgname}-docs @@ -581,6 +609,7 @@ export PATH="${cwd}/.bin:$PATH" --ninja \ --enable-lto \ --prefix=%{_prefix} \ + --use-prefix-to-find-headers \ --shared \ --libdir=%{_lib} \ %{ssl_configure} \ @@ -632,12 +661,16 @@ chrpath --delete %{buildroot}%{_bindir}/node # Rename the node binary mv %{buildroot}%{_bindir}/node %{buildroot}%{_bindir}/node-%{nodejs_pkg_major} -# Adjust the npm binaries -# 1. Replace all hasbangs with versioned ones -grep --extended-regexp --files-with-matches --recursive \ - '^#!/usr/bin/(env )?node($|[[:space:]])+' '%{buildroot}%{nodejs_private_sitelib}/npm/bin' \ -| xargs sed --in-place --regexp-extended \ - 's;^#!/usr/bin/(env )?node($|[[:space:]])+;#!/usr/bin/node-%{nodejs_pkg_major};' +# Adjust npm binaries +# 1. Replace all hashbangs with versioned ones +readonly NPM_DIR="%{buildroot}%{nodejs_private_sitelib}/npm" +readonly SHEBANG_ERE='^#!/usr/bin/(env\s+)?node\b' +readonly SHEBANG_FIX='#!%{_bindir}/node-%{nodejs_pkg_major}' +readonly -a npm_bin_dirs=("${NPM_DIR}/bin" "${NPM_DIR}/node_modules") + +find "${npm_bin_dirs[@]}" -type f \ +| xargs grep --extended-regexp --files-with-matches "${SHEBANG_ERE}" \ +| xargs sed --regexp-extended --in-place "s;${SHEBANG_ERE};${SHEBANG_FIX};" # 2. Replace original links with the adjusted ones for bin in npm npx; do @@ -658,6 +691,13 @@ ln -srf %{buildroot}%{_bindir}/npx-%{nodejs_pkg_major} \ %{buildroot}%{_bindir}/npx %endif +# Fix shell scripts that call 'node' as command +readonly -a known_shell_scripts=( + "${NPM_DIR}/bin/node-gyp-bin/node-gyp" + "${NPM_DIR}/node_modules/@npmcli/run-script/lib/node-gyp-bin/node-gyp" +) +sed --regexp-extended --in-place 's;\bnode(\s);%{_bindir}/node-%{nodejs_pkg_major}\1;' "${known_shell_scripts[@]}" + # Install library symlink ln -srf %{buildroot}%{_libdir}/libnode.so.%{nodejs_soversion} \ %{buildroot}%{_libdir}/libnode.so @@ -751,11 +791,6 @@ find %{buildroot}%{nodejs_private_sitelib}/npm \ chmod 0755 %{buildroot}%{nodejs_private_sitelib}/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin/node-gyp chmod 0755 %{buildroot}%{nodejs_private_sitelib}/npm/node_modules/node-gyp/bin/node-gyp.js -# Set the hashbang to use the matching Node.js interpreter -sed --in-place --regexp-extended \ - 's;^#!/usr/bin/env node($|\ |\t)+;#!/usr/bin/node-%{nodejs_pkg_major};g' \ - %{buildroot}%{nodejs_private_sitelib}/npm/node_modules/node-gyp/bin/node-gyp.js - # Drop the NPM builtin configuration in place sed -e 's#@SYSCONFDIR@#%{_sysconfdir}#g' \ %{SOURCE201} > %{buildroot}%{nodejs_private_sitelib}/npm/npmrc @@ -796,6 +831,13 @@ install -Dpm0644 %{SOURCE204} %{buildroot}%{_rpmconfigdir}/fileattrs/nodejs%{nod %check +#run unit test that should pass from list +LD_LIBRARY_PATH=%{buildroot}%{_libdir} \ + bash %{SOURCE300} \ + %{buildroot}/%{_bindir}/node-%{nodejs_pkg_major} \ + %{_builddir}/node-v%{nodejs_version}/test/ \ + %{SOURCE301} + # Fail the build if the versions don't match LD_LIBRARY_PATH=%{buildroot}%{_libdir} %{buildroot}/%{_bindir}/node-%{nodejs_pkg_major} -e "require('assert').equal(process.versions.node, '%{nodejs_version}')" LD_LIBRARY_PATH=%{buildroot}%{_libdir} %{buildroot}/%{_bindir}/node-%{nodejs_pkg_major} -e "require('assert').equal(process.versions.v8.replace(/-node\.\d+$/, ''), '%{v8_version}')" @@ -932,6 +974,66 @@ end %changelog ## START: Generated by rpmautospec +* Mon Mar 30 2026 Andrei Radchenko - 1:22.22.2-1 +- Update to version 22.22.2 +- introduced patch updating deps/nghttp2 to v 1.68.1 for CVE-2026-27135 +- disabled failing tests in nghttp2 due to newer version +- patch for npm/braces CVE-2026-25547 + +* Wed Mar 25 2026 Andrei Radchenko - 1:22.22.0-4 +- sources: changed ICU version syntax + +* Tue Jan 20 2026 Andrei Radchenko - 1:22.22.0-3 +- Bump release to get correct RHEL build + +* Fri Jan 16 2026 tjuhasz - 1:22.22.0-2 +- Filter for nodejs22.fmf in gating plan + +* Wed Jan 14 2026 tjuhasz - 1:22.22.0-1 +- Update to 22.22.0 + +* Thu Dec 04 2025 tjuhasz - 1:22.19.0-3 +- Unit-tests adjustment - disable internet/test-dgram-membership + +* Wed Sep 03 2025 tjuhasz - 1:22.19.0-2 +- Add patch to prevent fips usage segfault + +* Fri Aug 29 2025 Andrei Radchenko - 1:22.19.0-1 +- Update to version 22.19.0 + +* Fri Aug 29 2025 Andrei Radchenko - 1:22.16.0-6 +- configure.py: use local headers for building native addons when available + +* Fri Aug 29 2025 Andrei Radchenko - 1:22.16.0-5 +- spec: fix node binary calls to use versioned binary + +* Wed Aug 20 2025 Andrei Radchenko - 1:22.16.0-4 +- Test plan adjustments + +* Thu Jul 31 2025 Andrei Radchenko - 1:22.16.0-3 +- spec: devel packages explicitly conflicts + +* Fri Jun 20 2025 tjuhasz - 1:22.16.0-2 +- Add rpminspect config to repo + +* Tue May 27 2025 Andrei Radchenko - 1:22.16.0-1 +- Update to version 22.16.0 + +* Tue May 20 2025 tjuhasz - 1:22.15.0-3 +- Make grep Source stricter in nodejs-tarball + +* Tue May 20 2025 tjuhasz - 1:22.15.0-2 +- Add unit-test during build for nodejs22 + +* Thu Apr 24 2025 tjuhasz - 1:22.15.0-1 +- Update to version 22.15.0 + +* Tue Apr 22 2025 tjuhasz - 1:22.13.1-6 +- Update c-ares with fix for CVE-2025-31498 + +* Thu Mar 06 2025 Jan StanÄ›k - 1:22.13.1-5 +- Revert "Generate only versioned rpms" + * Tue Feb 25 2025 Jan StanÄ›k - 1:22.13.1-4 - Use stream-specific ABI dependency generator diff --git a/sources b/sources index 7338eb9..947f82e 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (icu4c-76_1-data-bin-b.zip) = 098326fbb0f4a1b70a314985cbe6918f3fec94feb17236dcf8efbc516e139294ec96ae49210e11ee40f4de1ac6977e939cbfd6087009be057b8a60d3ad01daad -SHA512 (icu4c-76_1-data-bin-l.zip) = 1359ff28bad54f73fe29cc5c4fffb4c11c64399ddcc39bea2ee60b5d3672e7f79546a2255d604474cbd861791c11e62eb50bcecc0cf2cf9a7ece59180e8520fc -SHA512 (node-v22.13.1-stripped.tar.gz) = 0e38b017a4dbc2532287e582d0492eaef6971db987722f5497e1d0875e83f1d0ab00c5d31b6842692f07538e49bdaada8cd997af2b200f4b7f47378fcb81c4ee +SHA512 (icu4c-78.2-data-bin-b.zip) = 032a1e519bf92dfa7936ef85ebed697550dbcb4e32c6ecd28ffecb158a403eeff6c0a3545b2551eba73f288e31693be6880e202a38cd86c129dffa395e8ab625 +SHA512 (icu4c-78.2-data-bin-l.zip) = c0b46de115332940d3276763904caa6257eb516edce4382632f4b96a5b010fee4cb06a5e10ef5eee2f881515c1ee8277d9ae59015f6de6fe1d175b9d00dbb1ca +SHA512 (node-v22.22.2-stripped.tar.gz) = 82c3357cce10a3fe89373ec4e3460af5992d853f28a7339358a3f910959e7b17987c8eb1748d9c3033d4c642701d321e2265cc0ac004a218860da4eda2971226 diff --git a/test-runner.sh b/test-runner.sh new file mode 100755 index 0000000..8ece02e --- /dev/null +++ b/test-runner.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +NODE_BIN="$1" +PARENT_TEST_FOLDER="$2" +TEST_LIST_FILE="$3" + +# At most 10 min per test +TIMEOUT_DURATION=600 +# Exit code +FINAL_RESULT=0 +ARCH=$(uname -m) + +echo "Started test run:" +# Run the list of test +while IFS= read -r test_line; do + # ignore commented lines + if [[ "$test_line" =~ ^# ]]; then + continue + fi + # If test has specified ARCH which it should be skipped + # Extract it + TEST_PATH=$(echo "$test_line" | awk '{print $1}') + IGNORE_ARCHES=$(echo "$test_line" |\ + awk '{for (i=2; i<=NF; i++) printf "%s ", $i; print ""}') + + # Skip test for specified ARCH + for ARCH_IGNORE in $IGNORE_ARCHES; do + if [[ "$ARCH_IGNORE" == "$ARCH" ]]; then + continue 2 + fi + done + + # Construct test path + TEST_SCRIPT="$PARENT_TEST_FOLDER/$TEST_PATH" + + if [ ! -f "$TEST_SCRIPT" ]; then + continue + fi + + TEST_OUTPUT=$(timeout "$TIMEOUT_DURATION" "$NODE_BIN" "$TEST_SCRIPT" 2>&1) + TEST_RESULT=$? + + # Handle test result + if [ $TEST_RESULT -ne 0 ]; then + FINAL_RESULT=1 + if [ $TEST_RESULT -eq 124 ]; then + echo "Test timed out: $TEST_SCRIPT" + else + echo "Test failed: $TEST_SCRIPT" + fi + echo "Test failure message:" + echo "$TEST_OUTPUT" + fi +done < "$TEST_LIST_FILE" + +if [ $FINAL_RESULT -eq 0 ]; then + echo "All tests succesfully passed." +fi +exit $FINAL_RESULT diff --git a/test-should-pass.txt b/test-should-pass.txt new file mode 100644 index 0000000..4ea6f21 --- /dev/null +++ b/test-should-pass.txt @@ -0,0 +1,3847 @@ +# List of supported tests +# +# Architectures which are to be ignored are listed after the test +# for example: abort/test-abort-fatal-error.js i686 +# won't be runned for i686 architecture +# +# Each exception should be explained with a comment +# containing date and a short description of the problem +# +abort/test-abort-fatal-error.js +abort/test-abort-uncaught-exception.js +abort/test-addon-register-signal-handler.js +abort/test-addon-uv-handle-leak.js +abort/test-http-parser-consume.js +abort/test-process-abort-exitcode.js +abort/test-signal-handler.js +abort/test-worker-abort-uncaught-exception.js +abort/test-zlib-invalid-internals-usage.js +async-hooks/hook-checks.js +async-hooks/init-hooks.js +async-hooks/test-async-await.js +async-hooks/test-async-exec-resource-http-32060.js +async-hooks/test-async-exec-resource-http-agent.js +async-hooks/test-async-exec-resource-http.js +async-hooks/test-async-exec-resource-match.js +async-hooks/test-async-local-storage-args.js +async-hooks/test-async-local-storage-async-await.js +async-hooks/test-async-local-storage-async-functions.js +async-hooks/test-async-local-storage-dgram.js +async-hooks/test-async-local-storage-enable-disable.js +async-hooks/test-async-local-storage-enter-with.js +async-hooks/test-async-local-storage-errors.js +async-hooks/test-async-local-storage-gcable.js +async-hooks/test-async-local-storage-http-agent.js +async-hooks/test-async-local-storage-http.js +async-hooks/test-async-local-storage-misc-stores.js +async-hooks/test-async-local-storage-nested.js +async-hooks/test-async-local-storage-no-mix-contexts.js +async-hooks/test-async-local-storage-promises.js +async-hooks/test-async-local-storage-socket.js +async-hooks/test-async-local-storage-thenable.js +async-hooks/test-async-local-storage-tlssocket.js +async-hooks/test-async-wrap-providers.js +async-hooks/test-callback-error.js +async-hooks/test-crypto-pbkdf2.js +async-hooks/test-crypto-randomBytes.js +async-hooks/test-destroy-not-blocked.js +async-hooks/test-disable-in-init.js +async-hooks/test-embedder.api.async-resource.js +async-hooks/test-embedder.api.async-resource-no-type.js +async-hooks/test-embedder.api.async-resource.runInAsyncScope.js +async-hooks/test-emit-after-on-destroyed.js +async-hooks/test-emit-before-after.js +async-hooks/test-emit-before-on-destroyed.js +async-hooks/test-emit-init.js +async-hooks/test-enable-disable.js +async-hooks/test-enable-in-init.js +async-hooks/test-filehandle-no-reuse.js +async-hooks/test-fseventwrap.js +async-hooks/test-fsreqcallback-access.js +async-hooks/test-fsreqcallback-readFile.js +async-hooks/test-getaddrinforeqwrap.js +async-hooks/test-getnameinforeqwrap.js +async-hooks/test-graph.fsreq-readFile.js +async-hooks/test-graph.http.js +async-hooks/test-graph.intervals.js +async-hooks/test-graph.pipeconnect.js +async-hooks/test-graph.pipe.js +async-hooks/test-graph.shutdown.js +async-hooks/test-graph.statwatcher.js +async-hooks/test-graph.tcp.js +async-hooks/test-graph.timeouts.js +async-hooks/test-graph.tls-write-12.js +async-hooks/test-graph.tls-write.js +async-hooks/test-http-agent-handle-reuse-parallel.js +async-hooks/test-http-agent-handle-reuse-serial.js +async-hooks/test-httpparser.request.js +async-hooks/test-httpparser.response.js +async-hooks/test-httpparser-reuse.js +async-hooks/test-immediate.js +async-hooks/test-improper-order.js +async-hooks/test-improper-unwind.js +async-hooks/test-late-hook-enable.js +async-hooks/test-net-get-connections.js +async-hooks/test-nexttick-default-trigger.js +async-hooks/test-no-assert-when-disabled.js +async-hooks/test-pipeconnectwrap.js +async-hooks/test-pipewrap.js +async-hooks/test-promise.chain-promise-before-init-hooks.js +async-hooks/test-promise.js +async-hooks/test-promise.promise-before-init-hooks.js +async-hooks/test-querywrap.js +async-hooks/test-queue-microtask.js +async-hooks/test-shutdownwrap.js +async-hooks/test-signalwrap.js +async-hooks/test-statwatcher.js +async-hooks/test-tcpwrap.js +async-hooks/test-timers.setInterval.js +async-hooks/test-timers.setTimeout.js +async-hooks/test-tlswrap.js +async-hooks/test-ttywrap.readstream.js +async-hooks/test-udpsendwrap.js +async-hooks/test-udpwrap.js +async-hooks/test-unhandled-exception-valid-ids.js +async-hooks/test-unhandled-rejection-context.js +async-hooks/test-writewrap.js +async-hooks/test-zlib.zlib-binding.deflate.js +async-hooks/verify-graph.js +benchmark/test-bechmark-readline.js +benchmark/test-benchmark-assert.js +benchmark/test-benchmark-async-hooks.js +benchmark/test-benchmark-blob.js +benchmark/test-benchmark-buffer.js +benchmark/test-benchmark-child-process.js +benchmark/test-benchmark-cluster.js +benchmark/test-benchmark-dgram.js +benchmark/test-benchmark-dns.js +benchmark/test-benchmark-domain.js +benchmark/test-benchmark-es.js +benchmark/test-benchmark-esm.js +benchmark/test-benchmark-events.js +benchmark/test-benchmark-http2.js +benchmark/test-benchmark-http.js +benchmark/test-benchmark-mime.js +benchmark/test-benchmark-misc.js +benchmark/test-benchmark-module.js +benchmark/test-benchmark-net.js +benchmark/test-benchmark-os.js +benchmark/test-benchmark-path.js +benchmark/test-benchmark-process.js +benchmark/test-benchmark-querystring.js +benchmark/test-benchmark-streams.js +benchmark/test-benchmark-string_decoder.js +benchmark/test-benchmark-timers.js +benchmark/test-benchmark-tls.js +benchmark/test-benchmark-url.js +benchmark/test-benchmark-util.js +benchmark/test-benchmark-v8.js +benchmark/test-benchmark-validators.js +benchmark/test-benchmark-vm.js +benchmark/test-benchmark-websocket.js +benchmark/test-benchmark-webstreams.js +benchmark/test-benchmark-worker.js +benchmark/test-benchmark-zlib.js +common/arraystream.js +common/assertSnapshot.js +common/benchmark.js +common/child_process.js +common/countdown.js +common/cpu-prof.js +common/crypto.js +common/debugger.js +common/dns.js +common/fixtures.js +common/gc.js +common/globals.js +common/hijackstdio.js +common/http2.js +common/index.js +common/inspector-helper.js +common/internet.js +common/measure-memory.js +common/net.js +common/process-exit-code-cases.js +common/prof.js +common/report.js +common/sea.js +common/shared-lib-util.js +common/snapshot.js +common/test-error-reporter.js +common/tick.js +common/tls.js +common/tmpdir.js +common/udp.js +common/v8.js +common/wasi.js +common/wpt.js +es-module/test-cjs-esm-warn.js +es-module/test-cjs-legacyMainResolve.js +es-module/test-cjs-legacyMainResolve-permission.js +es-module/test-cjs-prototype-pollution.js +es-module/test-disable-require-module-with-detection.js +es-module/test-dynamic-import-script-lifetime.js +es-module/test-esm-cjs-builtins.js +es-module/test-esm-cjs-exports.js +es-module/test-esm-cjs-main.js +es-module/test-esm-data-urls.js +es-module/test-esm-dynamic-import-attribute.js +es-module/test-esm-dynamic-import-commonjs.js +es-module/test-esm-dynamic-import.js +es-module/test-esm-dynamic-import-mutating-fs.js +es-module/test-esm-encoded-path-native.js +es-module/test-esm-error-cache.js +es-module/test-esm-import-attributes-errors.js +es-module/test-esm-import-attributes-validation.js +es-module/test-esm-invalid-data-urls.js +es-module/test-esm-invalid-pjson.js +es-module/test-esm-loader-cache-clearing.js +es-module/test-esm-loader-modulemap.js +es-module/test-esm-loader-search.js +es-module/test-esm-long-path-win.js +es-module/test-esm-preserve-symlinks.js +es-module/test-esm-preserve-symlinks-main.js +es-module/test-esm-repl-imports.js +es-module/test-esm-repl.js +es-module/test-esm-symlink.js +es-module/test-esm-symlink-main.js +es-module/test-esm-symlink-type.js +es-module/test-esm-type-field-errors-2.js +es-module/test-esm-type-field-errors.js +es-module/test-esm-undefined-cjs-global-like-variables.js +es-module/test-esm-unknown-extension.js +es-module/test-esm-url-extname.js +es-module/test-esm-windows.js +es-module/test-loaders-hidden-from-users.js +es-module/test-require-module-cached-tla.js +es-module/test-require-module-conditional-exports.js +es-module/test-require-module-conditional-exports-module.js +es-module/test-require-module-cycle-cjs-esm-esm.js +es-module/test-require-module-cycle-esm-cjs-esm-esm.js +es-module/test-require-module-cycle-esm-cjs-esm.js +es-module/test-require-module-cycle-esm-esm-cjs-esm-esm.js +es-module/test-require-module-cycle-esm-esm-cjs-esm.js +es-module/test-require-module-default-extension.js +es-module/test-require-module-defined-esmodule.js +es-module/test-require-module-detect-entry-point-aou.js +es-module/test-require-module-detect-entry-point.js +es-module/test-require-module-dont-detect-cjs.js +es-module/test-require-module-dynamic-import-1.js +es-module/test-require-module-dynamic-import-2.js +es-module/test-require-module-dynamic-import-3.js +es-module/test-require-module-dynamic-import-4.js +es-module/test-require-module-error-catching.js +es-module/test-require-module-errors.js +es-module/test-require-module-feature-detect.js +es-module/test-require-module-implicit.js +es-module/test-require-module.js +es-module/test-require-module-preload.js +es-module/test-require-module-retry-import-errored.js +es-module/test-require-module-retry-import-evaluating.js +es-module/test-require-module-synchronous-rejection-handling.js +es-module/test-require-module-tla.js +es-module/test-require-module-tla-retry-import-2.js +es-module/test-require-module-tla-retry-import.js +es-module/test-require-module-tla-retry-require.js +es-module/test-require-module-transpiled.js +es-module/test-require-module-twice.js +es-module/test-require-module-warning.js +es-module/test-require-module-with-detection.js +es-module/test-require-node-modules-warning.js +es-module/test-vm-compile-function-leak.js +es-module/test-vm-compile-function-lineoffset.js +es-module/test-vm-contextified-script-leak.js +es-module/test-vm-main-context-default-loader.js +es-module/test-vm-source-text-module-leak.js +es-module/test-vm-synthetic-module-leak.js +es-module/test-wasm-memory-out-of-bound.js +es-module/test-wasm-simple.js +es-module/test-wasm-web-api.js +fixtures/aead-vectors.js +fixtures/a.js +fixtures/async-error.js +fixtures/baz.js +fixtures/cjs-module-wrap.js +fixtures/cjs-module-wrapper.js +fixtures/compile-cache-wrapper.js +fixtures/debugger-repeat-last.js +fixtures/debugger-util-regression-fixture.js +fixtures/deep-exit.js +fixtures/define-global.js +fixtures/deprecated.js +fixtures/deprecated-userland-class.js +fixtures/deprecated-userland-function.js +fixtures/deprecated-userland-subclass.js +fixtures/destroy-stdin.js +fixtures/disable-warning.js +fixtures/disable-warning-worker.js +fixtures/empty.js +fixtures/exports-function-with-param.js +fixtures/external-repl-module.js +fixtures/get-call-sites.js +fixtures/GH-1899-output.js +fixtures/inspector-open.js +fixtures/intrinsic-mutation.js +fixtures/is-object.js +fixtures/klass-with-fields.js +fixtures/linux-perf.js +fixtures/linux-perf-logger.js +fixtures/loader-is-internal-thread.js +fixtures/mime-whatwg-generated.js +fixtures/mime-whatwg.js +fixtures/monkey-patch-run-main.js +fixtures/no-wrapper.js +fixtures/overwrite-config-preload-module.js +fixtures/parent-process-nonpersistent.js +fixtures/path.js +fixtures/print-10-lines.js +fixtures/print +fixtures/printA.js +fixtures/printB.js +fixtures/print-chars.js +fixtures/printC.js +fixtures/print-delayed.js +fixtures/print-error-message.js +fixtures/repl-load-multiline.js +fixtures/repl-load-multiline-no-trailing-newline.js +fixtures/require-resolve.js +fixtures/semicolon.js +fixtures/spawn-worker-with-trace-exit.js +fixtures/test-nodetiming-uvmetricsinfo.js +fixtures/test-resolution-inspect-brk-resolver.js +fixtures/tls-connect.js +fixtures/url-idna.js +fixtures/url-searchparams.js +fixtures/url-setter-tests-additional.js +fixtures/url-tests-additional.js +fixtures/utf8-bom.js +fixtures/utf8-shebang-bom.js +fixtures/warnings.js +fixtures/worker-preload.js +internet/test-dgram-connect.js +# Disabled on 04.12.2025 +# As it failed on Konflux +# Basic UDP multicast test +# has issues with adjusting interfaces in certain environments +# internet/test-dgram-membership.js +internet/test-dns-cares-domains.js +internet/test-dns-regress-6244.js +internet/test-dns-setserver-in-callback-of-resolve4.js +internet/test-https-issue-43963.js +internet/test-trace-events-dns.js +message/console_assert.js +message/max_tick_depth.js +message/node_run_non_existent.js +message/util-inspect-error-cause.js +message/util_inspect_error.js +parallel/test-abortcontroller-internal.js +parallel/test-abortcontroller.js +parallel/test-aborted-util.js +parallel/test-abortsignal-cloneable.js +parallel/test-accessor-properties.js +parallel/test-arm-math-illegal-instruction.js +parallel/test-assert-async.js +parallel/test-assert-builtins-not-read-from-filesystem.js +parallel/test-assert-calltracker-calls.js +parallel/test-assert-calltracker-getCalls.js +parallel/test-assert-calltracker-report.js +parallel/test-assert-calltracker-verify.js +parallel/test-assert-checktag.js +parallel/test-assert-deep.js +parallel/test-assert-deep-with-error.js +parallel/test-assert-esm-cjs-message-verify.js +parallel/test-assert-fail-deprecation.js +parallel/test-assert-fail.js +parallel/test-assert-first-line.js +parallel/test-assert-if-error.js +parallel/test-assert.js +parallel/test-assert-objects.js +parallel/test-assert-typedarray-deepequal.js +parallel/test-async-hooks-async-await.js +parallel/test-async-hooks-asyncresource-constructor.js +parallel/test-async-hooks-close-during-destroy.js +parallel/test-async-hooks-constructor.js +parallel/test-async-hooks-correctly-switch-promise-hook.js +parallel/test-async-hooks-destroy-on-gc.js +parallel/test-async-hooks-disable-during-promise.js +parallel/test-async-hooks-disable-gc-tracking.js +parallel/test-async-hooks-enable-before-promise-resolve.js +parallel/test-async-hooks-enable-disable-enable.js +parallel/test-async-hooks-enable-disable.js +parallel/test-async-hooks-enable-during-promise.js +parallel/test-async-hooks-enable-recursive.js +parallel/test-async-hooks-execution-async-resource-await.js +parallel/test-async-hooks-execution-async-resource.js +parallel/test-async-hooks-fatal-error.js +parallel/test-async-hooks-http-agent-destroy.js +parallel/test-async-hooks-http-agent.js +parallel/test-async-hooks-http-parser-destroy.js +parallel/test-async-hooks-prevent-double-destroy.js +parallel/test-async-hooks-promise-enable-disable.js +parallel/test-async-hooks-promise.js +parallel/test-async-hooks-promise-triggerid.js +parallel/test-async-hooks-recursive-stack-runInAsyncScope.js +parallel/test-async-hooks-run-in-async-scope-caught-exception.js +parallel/test-async-hooks-run-in-async-scope-this-arg.js +parallel/test-async-hooks-top-level-clearimmediate.js +parallel/test-async-hooks-vm-gc.js +parallel/test-async-hooks-worker-asyncfn-terminate-1.js +parallel/test-async-hooks-worker-asyncfn-terminate-2.js +parallel/test-async-hooks-worker-asyncfn-terminate-3.js +parallel/test-async-hooks-worker-asyncfn-terminate-4.js +parallel/test-async-local-storage-bind.js +parallel/test-async-local-storage-contexts.js +parallel/test-async-local-storage-deep-stack.js +parallel/test-async-local-storage-exit-does-not-leak.js +parallel/test-async-local-storage-http-multiclients.js +parallel/test-async-local-storage-snapshot.js +parallel/test-asyncresource-bind.js +parallel/test-async-wrap-constructor.js +parallel/test-async-wrap-destroyid.js +parallel/test-async-wrap-pop-id-during-load.js +parallel/test-async-wrap-promise-after-enabled.js +parallel/test-async-wrap-tlssocket-asyncreset.js +parallel/test-async-wrap-trigger-id.js +parallel/test-async-wrap-uncaughtexception.js +parallel/test-atomics-wake.js +parallel/test-bad-unicode.js +parallel/test-bash-completion.js +parallel/test-beforeexit-event-exit.js +parallel/test-benchmark-cli.js +parallel/test-binding-constants.js +parallel/test-blob-createobjecturl.js +parallel/test-blob-file-backed.js +parallel/test-blob.js +parallel/test-blocklist-clone.js +parallel/test-blocklist.js +parallel/test-bootstrap-modules.js +parallel/test-broadcastchannel-custom-inspect.js +parallel/test-btoa-atob.js +parallel/test-buffer-alloc.js +parallel/test-buffer-arraybuffer.js +parallel/test-buffer-ascii.js +parallel/test-buffer-backing-arraybuffer.js +parallel/test-buffer-badhex.js +parallel/test-buffer-bigint64.js +parallel/test-buffer-bytelength.js +parallel/test-buffer-compare.js +parallel/test-buffer-compare-offset.js +parallel/test-buffer-concat.js +parallel/test-buffer-constants.js +parallel/test-buffer-constructor-deprecation-error.js +parallel/test-buffer-constructor-node-modules.js +parallel/test-buffer-constructor-node-modules-paths.js +parallel/test-buffer-constructor-outside-node-modules.js +parallel/test-buffer-copy.js +parallel/test-buffer-equals.js +parallel/test-buffer-failed-alloc-typed-arrays.js +parallel/test-buffer-fakes.js +parallel/test-buffer-fill.js +parallel/test-buffer-from.js +parallel/test-buffer-includes.js +parallel/test-buffer-indexof.js +parallel/test-buffer-inheritance.js +parallel/test-buffer-inspect.js +parallel/test-buffer-isascii.js +parallel/test-buffer-isencoding.js +parallel/test-buffer-isutf8.js +parallel/test-buffer-iterator.js +parallel/test-buffer-new.js +parallel/test-buffer-no-negative-allocation.js +parallel/test-buffer-nopendingdep-map.js +parallel/test-buffer-of-no-deprecation.js +parallel/test-buffer-over-max-length.js +parallel/test-buffer-parent-property.js +parallel/test-buffer-pending-deprecation.js +parallel/test-buffer-pool-untransferable.js +parallel/test-buffer-prototype-inspect.js +parallel/test-buffer-readdouble.js +parallel/test-buffer-readfloat.js +parallel/test-buffer-readint.js +parallel/test-buffer-read.js +parallel/test-buffer-readuint.js +parallel/test-buffer-resizable.js +parallel/test-buffer-safe-unsafe.js +parallel/test-buffer-set-inspect-max-bytes.js +parallel/test-buffer-sharedarraybuffer.js +parallel/test-buffer-slice.js +parallel/test-buffer-slow.js +parallel/test-buffer-swap.js +parallel/test-buffer-tojson.js +parallel/test-buffer-tostring.js +parallel/test-buffer-tostring-rangeerror.js +parallel/test-buffer-tostring-range.js +parallel/test-buffer-writedouble.js +parallel/test-buffer-write-fast.js +parallel/test-buffer-writefloat.js +parallel/test-buffer-writeint.js +parallel/test-buffer-write.js +parallel/test-buffer-writeuint.js +parallel/test-buffer-zero-fill-cli.js +parallel/test-buffer-zero-fill.js +parallel/test-buffer-zero-fill-reset.js +parallel/test-c-ares.js +parallel/test-child-process-advanced-serialization.js +parallel/test-child-process-advanced-serialization-largebuffer.js +parallel/test-child-process-advanced-serialization-splitted-length-field.js +parallel/test-child-process-bad-stdio.js +parallel/test-child-process-can-write-to-stdout.js +parallel/test-child-process-constructor.js +parallel/test-child-process-cwd.js +parallel/test-child-process-default-options.js +parallel/test-child-process-destroy.js +parallel/test-child-process-detached.js +parallel/test-child-process-dgram-reuseport.js +parallel/test-child-process-disconnect.js +parallel/test-child-process-double-pipe.js +parallel/test-child-process-env.js +parallel/test-child-process-exec-abortcontroller-promisified.js +parallel/test-child-process-exec-any-shells-windows.js +parallel/test-child-process-exec-cwd.js +parallel/test-child-process-exec-encoding.js +parallel/test-child-process-exec-env.js +parallel/test-child-process-exec-error.js +parallel/test-child-process-execfile.js +parallel/test-child-process-execfile-maxbuf.js +parallel/test-child-process-execFile-promisified-abortController.js +parallel/test-child-process-execfilesync-maxbuf.js +parallel/test-child-process-exec-kill-throws.js +parallel/test-child-process-exec-maxbuf.js +parallel/test-child-process-exec-std-encoding.js +parallel/test-child-process-exec-stdout-stderr-data-string.js +parallel/test-child-process-execsync-maxbuf.js +parallel/test-child-process-exec-timeout-expire.js +parallel/test-child-process-exec-timeout-kill.js +parallel/test-child-process-exec-timeout-not-expired.js +parallel/test-child-process-exit-code.js +parallel/test-child-process-flush-stdio.js +parallel/test-child-process-fork3.js +parallel/test-child-process-fork-abort-signal.js +parallel/test-child-process-fork-and-spawn.js +parallel/test-child-process-fork-args.js +parallel/test-child-process-fork-closed-channel-segfault.js +parallel/test-child-process-fork-close.js +parallel/test-child-process-fork-detached.js +parallel/test-child-process-fork-dgram.js +parallel/test-child-process-fork-exec-argv.js +parallel/test-child-process-fork-exec-path.js +parallel/test-child-process-fork-getconnections.js +parallel/test-child-process-fork.js +parallel/test-child-process-fork-net.js +parallel/test-child-process-fork-net-server.js +parallel/test-child-process-fork-net-socket.js +parallel/test-child-process-fork-no-shell.js +parallel/test-child-process-fork-ref2.js +parallel/test-child-process-fork-ref.js +parallel/test-child-process-fork-stdio.js +parallel/test-child-process-fork-stdio-string-variant.js +parallel/test-child-process-fork-timeout-kill-signal.js +parallel/test-child-process-http-socket-leak.js +parallel/test-child-process-internal.js +parallel/test-child-process-ipc.js +parallel/test-child-process-ipc-next-tick.js +parallel/test-child-process-kill.js +parallel/test-child-process-net-reuseport.js +parallel/test-child-process-no-deprecation.js +parallel/test-child-process-pipe-dataflow.js +parallel/test-child-process-promisified.js +parallel/test-child-process-recv-handle.js +parallel/test-child-process-reject-null-bytes.js +parallel/test-child-process-send-after-close.js +parallel/test-child-process-send-cb.js +parallel/test-child-process-send-keep-open.js +parallel/test-child-process-send-returns-boolean.js +parallel/test-child-process-send-type-error.js +parallel/test-child-process-send-utf8.js +parallel/test-child-process-server-close.js +parallel/test-child-process-set-blocking.js +parallel/test-child-process-silent.js +parallel/test-child-process-spawn-args.js +parallel/test-child-process-spawn-argv0.js +parallel/test-child-process-spawn-controller.js +parallel/test-child-process-spawn-error.js +parallel/test-child-process-spawn-event.js +parallel/test-child-process-spawn-shell.js +parallel/test-child-process-spawnsync-args.js +parallel/test-child-process-spawnsync-env.js +parallel/test-child-process-spawnsync-input.js +parallel/test-child-process-spawnsync.js +parallel/test-child-process-spawnsync-kill-signal.js +parallel/test-child-process-spawnsync-maxbuf.js +parallel/test-child-process-spawnsync-shell.js +parallel/test-child-process-spawnsync-timeout.js +parallel/test-child-process-spawnsync-validation-errors.js +parallel/test-child-process-spawn-timeout-kill-signal.js +parallel/test-child-process-spawn-typeerror.js +parallel/test-child-process-spawn-windows-batch-file.js +parallel/test-child-process-stdin-ipc.js +parallel/test-child-process-stdin.js +parallel/test-child-process-stdio-big-write-end.js +parallel/test-child-process-stdio-inherit.js +parallel/test-child-process-stdio.js +parallel/test-child-process-stdio-merge-stdouts-into-cat.js +parallel/test-child-process-stdio-overlapped.js +parallel/test-child-process-stdio-reuse-readable-stdio.js +parallel/test-child-process-stdout-flush-exit.js +parallel/test-child-process-stdout-flush.js +parallel/test-child-process-stdout-ipc.js +parallel/test-child-process-uid-gid.js +parallel/test-child-process-validate-stdio.js +parallel/test-child-process-windows-hide.js +parallel/test-cli-bad-options.js +parallel/test-client-request-destroy.js +parallel/test-cli-eval-event.js +parallel/test-cli-eval.js +parallel/test-cli-node-options-disallowed.js +parallel/test-cli-node-options-docs.js +parallel/test-cli-node-options.js +parallel/test-cli-node-print-help.js +parallel/test-cli-options-negation.js +parallel/test-cli-options-precedence.js +parallel/test-cli-permission-deny-fs.js +parallel/test-cli-permission-multiple-allow.js +parallel/test-cli-syntax-eval.js +parallel/test-cli-syntax-piped-bad.js +parallel/test-cli-syntax-piped-good.js +parallel/test-cluster-accept-fail.js +parallel/test-cluster-advanced-serialization.js +parallel/test-cluster-basic.js +parallel/test-cluster-bind-privileged-port.js +parallel/test-cluster-bind-twice.js +parallel/test-cluster-call-and-destroy.js +parallel/test-cluster-child-index-dgram.js +parallel/test-cluster-child-index-net.js +parallel/test-cluster-concurrent-disconnect.js +parallel/test-cluster-cwd.js +parallel/test-cluster-dgram-1.js +parallel/test-cluster-dgram-2.js +parallel/test-cluster-dgram-bind-fd.js +parallel/test-cluster-dgram-ipv6only.js +parallel/test-cluster-dgram-reuse.js +parallel/test-cluster-dgram-reuseport.js +parallel/test-cluster-disconnect-before-exit.js +parallel/test-cluster-disconnect-exitedAfterDisconnect-race.js +parallel/test-cluster-disconnect-idle-worker.js +parallel/test-cluster-disconnect.js +parallel/test-cluster-disconnect-leak.js +parallel/test-cluster-disconnect-race.js +parallel/test-cluster-disconnect-unshared-tcp.js +parallel/test-cluster-disconnect-unshared-udp.js +parallel/test-cluster-disconnect-with-no-workers.js +parallel/test-cluster-eaccess.js +parallel/test-cluster-eaddrinuse.js +parallel/test-cluster-fork-env.js +parallel/test-cluster-fork-stdio.js +parallel/test-cluster-fork-windowsHide.js +parallel/test-cluster-http-pipe.js +parallel/test-cluster-invalid-message.js +parallel/test-cluster-ipc-throw.js +parallel/test-cluster-kill-disconnect.js +parallel/test-cluster-kill-infinite-loop.js +parallel/test-cluster-listening-port.js +parallel/test-cluster-listen-pipe-readable-writable.js +parallel/test-cluster-message.js +parallel/test-cluster-net-listen-backlog.js +parallel/test-cluster-net-listen-ipv6only-false.js +parallel/test-cluster-net-listen.js +parallel/test-cluster-net-listen-relative-path.js +parallel/test-cluster-net-reuseport.js +parallel/test-cluster-net-send.js +parallel/test-cluster-net-server-drop-connection.js +parallel/test-cluster-primary-error.js +parallel/test-cluster-primary-kill.js +parallel/test-cluster-process-disconnect.js +parallel/test-cluster-rr-domain-listen.js +parallel/test-cluster-rr-handle-close.js +parallel/test-cluster-rr-handle-keep-loop-alive.js +parallel/test-cluster-rr-handle-ref-unref.js +parallel/test-cluster-rr-ref.js +parallel/test-cluster-send-deadlock.js +parallel/test-cluster-send-handle-twice.js +parallel/test-cluster-send-socket-to-worker-http-server.js +parallel/test-cluster-server-restart-none.js +parallel/test-cluster-server-restart-rr.js +parallel/test-cluster-setup-primary-argv.js +parallel/test-cluster-setup-primary-cumulative.js +parallel/test-cluster-setup-primary-emit.js +parallel/test-cluster-setup-primary.js +parallel/test-cluster-setup-primary-multiple.js +parallel/test-cluster-shared-handle-bind-error.js +parallel/test-cluster-shared-handle-bind-privileged-port.js +parallel/test-cluster-shared-leak.js +parallel/test-cluster-uncaught-exception.js +parallel/test-cluster-worker-constructor.js +parallel/test-cluster-worker-death.js +parallel/test-cluster-worker-destroy.js +parallel/test-cluster-worker-disconnect.js +parallel/test-cluster-worker-disconnect-on-error.js +parallel/test-cluster-worker-events.js +parallel/test-cluster-worker-exit.js +parallel/test-cluster-worker-forced-exit.js +parallel/test-cluster-worker-handle-close.js +parallel/test-cluster-worker-init.js +parallel/test-cluster-worker-isconnected.js +parallel/test-cluster-worker-isdead.js +parallel/test-cluster-worker-kill.js +parallel/test-cluster-worker-kill-signal.js +parallel/test-cluster-worker-no-exit.js +parallel/test-cluster-worker-wait-server-close.js +parallel/test-code-cache.js +parallel/test-common-countdown.js +parallel/test-common-expect-warning.js +parallel/test-common-gc.js +parallel/test-common.js +parallel/test-common-must-not-call.js +parallel/test-compile-cache-api-env.js +parallel/test-compile-cache-api-error.js +parallel/test-compile-cache-api-flush.js +parallel/test-compile-cache-api-permission.js +parallel/test-compile-cache-api-success.js +parallel/test-compile-cache-api-tmpdir.js +parallel/test-compile-cache-bad-syntax.js +parallel/test-compile-cache-disable.js +parallel/test-compile-cache-dynamic-import.js +parallel/test-compile-cache-esm.js +parallel/test-compile-cache-existing-directory.js +parallel/test-compile-cache-permission-allowed.js +parallel/test-compile-cache-permission-disallowed.js +parallel/test-compile-cache-success.js +parallel/test-compile-cache-updated-file.js +parallel/test-compression-decompression-stream.js +parallel/test-console-assign-undefined.js +parallel/test-console-async-write-error.js +parallel/test-console-clear.js +parallel/test-console-count.js +parallel/test-console-diagnostics-channels.js +parallel/test-console-formatTime.js +parallel/test-console-group.js +parallel/test-console-instance.js +parallel/test-console-issue-43095.js +parallel/test-console.js +parallel/test-console-log-stdio-broken-dest.js +parallel/test-console-log-throw-primitive.js +parallel/test-console-methods.js +parallel/test-console-no-swallow-stack-overflow.js +parallel/test-console-not-call-toString.js +parallel/test-console-self-assign.js +parallel/test-console-stdio-setters.js +parallel/test-console-sync-write-error.js +parallel/test-console-table.js +parallel/test-console-tty-colors.js +parallel/test-console-with-frozen-intrinsics.js +parallel/test-constants.js +parallel/test-corepack-version.js +parallel/test-coverage-with-inspector-disabled.js +parallel/test-crypto-aes-wrap.js +parallel/test-crypto-async-sign-verify.js +parallel/test-crypto-authenticated.js +parallel/test-crypto-authenticated-stream.js +parallel/test-crypto-cipheriv-decipheriv.js +parallel/test-crypto-classes.js +parallel/test-crypto-des3-wrap.js +parallel/test-crypto-dh-constructor.js +parallel/test-crypto-dh-curves.js +parallel/test-crypto-dh-errors.js +parallel/test-crypto-dh-generate-keys.js +parallel/test-crypto-dh-group-setters.js +parallel/test-crypto-dh.js +parallel/test-crypto-dh-leak.js +parallel/test-crypto-dh-modp2.js +parallel/test-crypto-dh-modp2-views.js +parallel/test-crypto-dh-odd-key.js +parallel/test-crypto-dh-padding.js +parallel/test-crypto-dh-shared.js +parallel/test-crypto-dh-stateless.js +parallel/test-crypto-domain.js +parallel/test-crypto-domains.js +parallel/test-crypto-ecb.js +parallel/test-crypto-ecdh-convert-key.js +parallel/test-crypto-encoding-validation-error.js +parallel/test-crypto-from-binary.js +parallel/test-crypto-gcm-explicit-short-tag.js +parallel/test-crypto-gcm-implicit-short-tag.js +parallel/test-crypto-getcipherinfo.js +parallel/test-crypto-hash.js +parallel/test-crypto-hash-stream-pipe.js +parallel/test-crypto-hkdf.js +parallel/test-crypto-hmac.js +# Test disabled on 19.5.2025 as: +# There have been changes to the available cipher suite in RHEL 10 +# And test required cipher aes-256 is no longer present. +# parallel/test-crypto.js +parallel/test-crypto-keygen-async-dsa.js +parallel/test-crypto-keygen-async-dsa-key-object.js +parallel/test-crypto-keygen-async-elliptic-curve-jwk-ec.js +parallel/test-crypto-keygen-async-elliptic-curve-jwk.js +parallel/test-crypto-keygen-async-elliptic-curve-jwk-rsa.js +parallel/test-crypto-keygen-async-encrypted-private-key-der.js +parallel/test-crypto-keygen-async-encrypted-private-key.js +parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted.js.js +parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted-p256.js +parallel/test-crypto-keygen-async-explicit-elliptic-curve.js +parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted.js +parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js +parallel/test-crypto-keygen-async-named-elliptic-curve.js +parallel/test-crypto-keygen-async-rsa.js +parallel/test-crypto-keygen-bit-length.js +parallel/test-crypto-keygen-deprecation.js +parallel/test-crypto-keygen-dh-classic.js +parallel/test-crypto-keygen-duplicate-deprecated-option.js +parallel/test-crypto-keygen-eddsa.js +parallel/test-crypto-keygen-empty-passphrase-no-error.js +parallel/test-crypto-keygen-empty-passphrase-no-prompt.js +parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js +parallel/test-crypto-keygen-invalid-parameter-encoding-ec.js +parallel/test-crypto-keygen.js +parallel/test-crypto-keygen-key-objects.js +parallel/test-crypto-keygen-key-object-without-encoding.js +parallel/test-crypto-keygen-missing-oid.js +parallel/test-crypto-keygen-non-standard-public-exponent.js +parallel/test-crypto-keygen-no-rsassa-pss-params.js +parallel/test-crypto-keygen-promisify.js +parallel/test-crypto-keygen-rfc8017-9-1.js +parallel/test-crypto-keygen-rfc8017-a-2-3.js +parallel/test-crypto-keygen-rsa-pss.js +parallel/test-crypto-keygen-sync.js +parallel/test-crypto-key-objects-messageport.js +parallel/test-crypto-key-objects-to-crypto-key.js +parallel/test-crypto-lazy-transform-writable.js +parallel/test-crypto-oneshot-hash.js +parallel/test-crypto-op-during-process-exit.js +parallel/test-crypto-padding-aes256.js +parallel/test-crypto-padding.js +parallel/test-crypto-pbkdf2.js +parallel/test-crypto-prime.js +parallel/test-crypto-private-decrypt-gh32240.js +parallel/test-crypto-psychic-signatures.js +parallel/test-crypto-publicDecrypt-fails-first-time.js +parallel/test-crypto-randomfillsync-regression.js +parallel/test-crypto-random.js +parallel/test-crypto-randomuuid.js +parallel/test-crypto-scrypt.js +parallel/test-crypto-secret-keygen.js +parallel/test-crypto-secure-heap.js +parallel/test-crypto-stream.js +parallel/test-crypto-subtle-zero-length.js +parallel/test-crypto-update-encoding.js +parallel/test-crypto-verify-failure.js +parallel/test-crypto-webcrypto-aes-decrypt-tag-too-small.js +parallel/test-crypto-worker-thread.js +parallel/test-crypto-x509.js +parallel/test-cwd-enoent.js +parallel/test-cwd-enoent-preload.js +parallel/test-cwd-enoent-repl.js +parallel/test-data-url.js +parallel/test-datetime-change-notify.js +parallel/test-debugger-backtrace.js +parallel/test-debugger-break.js +parallel/test-debugger-breakpoint-exists.js +parallel/test-debugger-clear-breakpoints.js +parallel/test-debugger-exceptions.js +parallel/test-debugger-exec.js +parallel/test-debugger-heap-profiler.js +parallel/test-debugger-list.js +parallel/test-debugger-low-level.js +parallel/test-debugger-object-type-remote-object.js +parallel/test-debugger-pid.js +parallel/test-debugger-preserve-breaks.js +parallel/test-debugger-profile.js +parallel/test-debugger-random-port.js +parallel/test-debugger-random-port-with-inspect-port.js +parallel/test-debugger-repeat-last.js +parallel/test-debugger-restart-message.js +parallel/test-debugger-run-after-quit-restart.js +parallel/test-debugger-sb-before-load.js +parallel/test-debugger-scripts.js +parallel/test-debugger-unavailable-port.js +parallel/test-debugger-use-strict.js +parallel/test-debugger-watch-validation.js +parallel/test-debugger-websocket-secret-mismatch.js +parallel/test-debug-process.js +parallel/test-debug-v8-fast-api.js +parallel/test-delayed-require.js +parallel/test-destroy-socket-in-lookup.js +parallel/test-dgram-abort-closed.js +parallel/test-dgram-address.js +parallel/test-dgram-bind-default-address.js +parallel/test-dgram-bind-error-repeat.js +parallel/test-dgram-bind-fd-error.js +parallel/test-dgram-bind-fd.js +parallel/test-dgram-bind.js +parallel/test-dgram-bind-socket-close-before-cluster-reply.js +parallel/test-dgram-bind-socket-close-before-lookup.js +parallel/test-dgram-blocklist.js +parallel/test-dgram-bytes-length.js +parallel/test-dgram-close-during-bind.js +parallel/test-dgram-close-in-listening.js +parallel/test-dgram-close-is-not-callback.js +parallel/test-dgram-close.js +parallel/test-dgram-close-signal.js +parallel/test-dgram-cluster-bind-error.js +parallel/test-dgram-cluster-close-during-bind.js +parallel/test-dgram-cluster-close-in-listening.js +parallel/test-dgram-connect.js +parallel/test-dgram-connect-send-callback-buffer.js +parallel/test-dgram-connect-send-callback-buffer-length.js +parallel/test-dgram-connect-send-callback-multi-buffer.js +parallel/test-dgram-connect-send-default-host.js +parallel/test-dgram-connect-send-empty-array.js +parallel/test-dgram-connect-send-empty-buffer.js +parallel/test-dgram-connect-send-empty-packet.js +parallel/test-dgram-connect-send-multi-buffer-copy.js +parallel/test-dgram-connect-send-multi-string-array.js +parallel/test-dgram-create-socket-handle-fd.js +parallel/test-dgram-create-socket-handle.js +parallel/test-dgram-createSocket-type.js +parallel/test-dgram-custom-lookup.js +parallel/test-dgram-deprecation-error.js +parallel/test-dgram-error-message-address.js +parallel/test-dgram-exclusive-implicit-bind.js +parallel/test-dgram-implicit-bind.js +parallel/test-dgram-ipv6only.js +parallel/test-dgram-listen-after-bind.js +parallel/test-dgram-membership.js +parallel/test-dgram-msgsize.js +parallel/test-dgram-multicast-loopback.js +parallel/test-dgram-multicast-set-interface.js +parallel/test-dgram-multicast-setTTL.js +parallel/test-dgram-oob-buffer.js +parallel/test-dgram-recv-error.js +parallel/test-dgram-ref.js +parallel/test-dgram-reuseport.js +parallel/test-dgram-send-address-types.js +parallel/test-dgram-send-bad-arguments.js +parallel/test-dgram-send-callback-buffer-empty-address.js +parallel/test-dgram-send-callback-buffer.js +parallel/test-dgram-send-callback-buffer-length-empty-address.js +parallel/test-dgram-send-callback-buffer-length.js +parallel/test-dgram-send-callback-multi-buffer-empty-address.js +parallel/test-dgram-send-callback-multi-buffer.js +parallel/test-dgram-send-callback-recursive.js +parallel/test-dgram-send-cb-quelches-error.js +parallel/test-dgram-send-default-host.js +parallel/test-dgram-send-empty-array.js +parallel/test-dgram-send-empty-buffer.js +parallel/test-dgram-send-empty-packet.js +parallel/test-dgram-send-error.js +parallel/test-dgram-send-invalid-msg-type.js +parallel/test-dgram-send-multi-buffer-copy.js +parallel/test-dgram-send-multi-string-array.js +parallel/test-dgram-send-queue-info.js +parallel/test-dgram-sendto.js +parallel/test-dgram-setBroadcast.js +parallel/test-dgram-setTTL.js +parallel/test-dgram-socket-buffer-size.js +parallel/test-dgram-udp4.js +parallel/test-dgram-udp6-link-local-address.js +parallel/test-dgram-udp6-send-default-host.js +parallel/test-dgram-unref-in-cluster.js +parallel/test-dgram-unref.js +parallel/test-diagnostic-channel-http-request-created.js +parallel/test-diagnostic-channel-http-response-created.js +parallel/test-diagnostics-channel-bind-store.js +parallel/test-diagnostics-channel-has-subscribers.js +parallel/test-diagnostics-channel-http.js +parallel/test-diagnostics-channel-http-server-start.js +parallel/test-diagnostics-channel-memory-leak.js +parallel/test-diagnostics-channel-module-import-error.js +parallel/test-diagnostics-channel-module-import.js +parallel/test-diagnostics-channel-module-require-error.js +parallel/test-diagnostics-channel-module-require.js +parallel/test-diagnostics-channel-net.js +parallel/test-diagnostics-channel-object-channel-pub-sub.js +parallel/test-diagnostics-channel-process.js +parallel/test-diagnostics-channel-pub-sub.js +parallel/test-diagnostics-channel-safe-subscriber-errors.js +parallel/test-diagnostics-channel-symbol-named.js +parallel/test-diagnostics-channel-sync-unsubscribe.js +parallel/test-diagnostics-channel-tracing-channel-args-types.js +parallel/test-diagnostics-channel-tracing-channel-callback-early-exit.js +parallel/test-diagnostics-channel-tracing-channel-callback-error.js +parallel/test-diagnostics-channel-tracing-channel-callback.js +parallel/test-diagnostics-channel-tracing-channel-callback-run-stores.js +parallel/test-diagnostics-channel-tracing-channel-has-subscribers.js +parallel/test-diagnostics-channel-tracing-channel-promise-early-exit.js +parallel/test-diagnostics-channel-tracing-channel-promise-error.js +parallel/test-diagnostics-channel-tracing-channel-promise.js +parallel/test-diagnostics-channel-tracing-channel-promise-run-stores.js +parallel/test-diagnostics-channel-tracing-channel-sync-early-exit.js +parallel/test-diagnostics-channel-tracing-channel-sync-error.js +parallel/test-diagnostics-channel-tracing-channel-sync.js +parallel/test-diagnostics-channel-tracing-channel-sync-run-stores.js +parallel/test-diagnostics-channel-udp.js +parallel/test-diagnostics-channel-worker-threads.js +parallel/test-directory-import.js +parallel/test-disable-proto-delete.js +parallel/test-disable-proto-throw.js +parallel/test-disable-sigusr1.js +parallel/test-dns-cancel-reverse-lookup.js +parallel/test-dns-channel-cancel.js +parallel/test-dns-channel-cancel-promise.js +parallel/test-dns-channel-timeout.js +parallel/test-dns-default-order-ipv4.js +parallel/test-dns-default-order-ipv6.js +parallel/test-dns-default-order-verbatim.js +parallel/test-dns-get-server.js +parallel/test-dns.js +parallel/test-dns-lookup.js +parallel/test-dns-lookup-promises.js +parallel/test-dns-lookup-promises-options-deprecated.js +parallel/test-dns-lookupService.js +parallel/test-dns-lookupService-promises.js +parallel/test-dns-memory-error.js +parallel/test-dns-multi-channel.js +parallel/test-dns-perf_hooks.js +parallel/test-dns-promises-exists.js +parallel/test-dns-resolveany-bad-ancount.js +parallel/test-dns-resolveany.js +parallel/test-dns-resolvens-typeerror.js +parallel/test-dns-resolve-promises.js +parallel/test-dns-set-default-order.js +parallel/test-dns-setlocaladdress.js +parallel/test-dns-setservers-type-check.js +parallel/test-dns-setserver-when-querying.js +parallel/test-domain-abort-on-uncaught.js +parallel/test-domain-add-remove.js +parallel/test-domain-async-id-map-leak.js +parallel/test-domain-bind-timeout.js +parallel/test-domain-crypto.js +parallel/test-domain-dep0097.js +parallel/test-domain-ee-error-listener.js +parallel/test-domain-ee-implicit.js +parallel/test-domain-ee.js +parallel/test-domain-emit-error-handler-stack.js +parallel/test-domain-enter-exit.js +parallel/test-domain-error-types.js +parallel/test-domain-from-timer.js +parallel/test-domain-fs-enoent-stream.js +parallel/test-domain-http-server.js +parallel/test-domain-implicit-binding.js +parallel/test-domain-implicit-fs.js +parallel/test-domain-intercept.js +parallel/test-domain-load-after-set-uncaught-exception-capture.js +parallel/test-domain-multi.js +parallel/test-domain-multiple-errors.js +parallel/test-domain-nested.js +parallel/test-domain-nested-throw.js +parallel/test-domain-nexttick.js +parallel/test-domain-no-error-handler-abort-on-uncaught-0.js +parallel/test-domain-no-error-handler-abort-on-uncaught-1.js +parallel/test-domain-no-error-handler-abort-on-uncaught-2.js +parallel/test-domain-no-error-handler-abort-on-uncaught-3.js +parallel/test-domain-no-error-handler-abort-on-uncaught-4.js +parallel/test-domain-no-error-handler-abort-on-uncaught-5.js +parallel/test-domain-no-error-handler-abort-on-uncaught-6.js +parallel/test-domain-no-error-handler-abort-on-uncaught-7.js +parallel/test-domain-no-error-handler-abort-on-uncaught-8.js +parallel/test-domain-no-error-handler-abort-on-uncaught-9.js +parallel/test-domain-promise.js +parallel/test-domain-run.js +parallel/test-domain-safe-exit.js +parallel/test-domain-set-uncaught-exception-capture-after-load.js +parallel/test-domain-stack-empty-in-process-uncaughtexception.js +parallel/test-domain-stack.js +parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js +parallel/test-domain-thrown-error-handler-stack.js +parallel/test-domain-timer.js +parallel/test-domain-timers.js +parallel/test-domain-timers-uncaught-exception.js +parallel/test-domain-top-level-error-handler-clears-stack.js +parallel/test-domain-top-level-error-handler-throw.js +parallel/test-domain-uncaught-exception.js +parallel/test-domain-vm-promise-isolation.js +parallel/test-domain-with-abort-on-uncaught-exception.js +parallel/test-domexception-cause.js +parallel/test-dotenv-edge-cases.js +parallel/test-dotenv-node-options.js +parallel/test-double-tls-client.js +parallel/test-double-tls-server.js +parallel/test-dsa-fips-invalid-key.js +parallel/test-dummy-stdio.js +parallel/test-emit-after-uncaught-exception.js +parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js +parallel/test-env-var-no-warnings.js +parallel/test-err-name-deprecation.js +parallel/test-error-aggregateTwoErrors.js +parallel/test-error-format-list.js +parallel/test-error-prepare-stack-trace.js +parallel/test-error-reporting.js +parallel/test-errors-aborterror.js +parallel/test-errors-hide-stack-frames.js +parallel/test-errors-systemerror-frozen-intrinsics.js +parallel/test-errors-systemerror.js +parallel/test-errors-systemerror-stackTraceLimit-custom-setter.js +parallel/test-errors-systemerror-stackTraceLimit-deleted-and-Error-sealed.js +parallel/test-errors-systemerror-stackTraceLimit-deleted.js +parallel/test-errors-systemerror-stackTraceLimit-has-only-a-getter.js +parallel/test-errors-systemerror-stackTraceLimit-not-writable.js +parallel/test-eslint-alphabetize-errors.js +parallel/test-eslint-alphabetize-primordials.js +parallel/test-eslint-async-iife-no-unused-result.js +parallel/test-eslint-avoid-prototype-pollution.js +parallel/test-eslint-crypto-check.js +parallel/test-eslint-documented-deprecation-codes.js +parallel/test-eslint-documented-errors.js +parallel/test-eslint-duplicate-requires.js +parallel/test-eslint-eslint-check.js +parallel/test-eslint-inspector-check.js +parallel/test-eslint-lowercase-name-for-primitive.js +parallel/test-eslint-no-array-destructuring.js +parallel/test-eslint-non-ascii-character.js +parallel/test-eslint-no-unescaped-regexp-dot.js +parallel/test-eslint-prefer-assert-iferror.js +parallel/test-eslint-prefer-assert-methods.js +parallel/test-eslint-prefer-common-mustnotcall.js +parallel/test-eslint-prefer-common-mustsucceed.js +parallel/test-eslint-prefer-optional-chaining.js +parallel/test-eslint-prefer-primordials.js +parallel/test-eslint-prefer-proto.js +parallel/test-eslint-prefer-util-format-errors.js +parallel/test-eslint-require-common-first.js +parallel/test-eslint-required-modules.js +parallel/test-esm-loader-hooks-inspect-brk.js +parallel/test-esm-loader-hooks-inspect-wait.js +parallel/test-eval-disallow-code-generation-from-strings.js +parallel/test-eval.js +parallel/test-eval-strict-referenceerror.js +parallel/test-event-capture-rejections.js +parallel/test-event-emitter-add-listeners.js +parallel/test-eventemitter-asyncresource.js +parallel/test-event-emitter-check-listener-leaks.js +parallel/test-event-emitter-emit-context.js +parallel/test-event-emitter-error-monitor.js +parallel/test-event-emitter-errors.js +parallel/test-event-emitter-get-max-listeners.js +parallel/test-event-emitter-invalid-listener.js +parallel/test-event-emitter-listener-count.js +parallel/test-event-emitter-listeners.js +parallel/test-event-emitter-listeners-side-effects.js +parallel/test-event-emitter-max-listeners.js +parallel/test-event-emitter-max-listeners-warning-for-null.js +parallel/test-event-emitter-max-listeners-warning-for-symbol.js +parallel/test-event-emitter-max-listeners-warning.js +parallel/test-event-emitter-method-names.js +parallel/test-event-emitter-modify-in-emit.js +parallel/test-event-emitter-no-error-provided-to-error-event.js +parallel/test-event-emitter-num-args.js +parallel/test-event-emitter-once.js +parallel/test-event-emitter-prepend.js +parallel/test-event-emitter-remove-all-listeners.js +parallel/test-event-emitter-remove-listeners.js +parallel/test-event-emitter-set-max-listeners-side-effects.js +parallel/test-event-emitter-special-event-names.js +parallel/test-event-emitter-subclass.js +parallel/test-event-emitter-symbols.js +parallel/test-events-customevent.js +parallel/test-events-getmaxlisteners.js +parallel/test-events-listener-count-with-listener.js +parallel/test-events-list.js +parallel/test-events-on-async-iterator.js +parallel/test-events-once.js +parallel/test-eventsource-disabled.js +parallel/test-eventsource.js +parallel/test-events-static-geteventlisteners.js +parallel/test-events-uncaught-exception-stack.js +parallel/test-eventtarget-brandcheck.js +parallel/test-event-target.js +parallel/test-eventtarget.js +parallel/test-eventtarget-memoryleakwarning.js +parallel/test-eventtarget-once-twice.js +parallel/test-exception-handler2.js +parallel/test-exception-handler.js +parallel/test-experimental-shared-value-conveyor.js +parallel/test-fetch-mock.js +parallel/test-filehandle-close.js +parallel/test-filehandle-readablestream.js +parallel/test-file.js +parallel/test-file-read-noexist.js +parallel/test-file-validate-mode-flag.js +parallel/test-file-write-stream2.js +parallel/test-file-write-stream3.js +parallel/test-file-write-stream4.js +parallel/test-file-write-stream5.js +parallel/test-file-write-stream.js +parallel/test-finalization-registry-shutdown.js +parallel/test-find-package-json.js +parallel/test-fixed-queue.js +parallel/test-force-repl.js +parallel/test-force-repl-with-eval.js +parallel/test-freelist.js +parallel/test-freeze-intrinsics.js +parallel/test-fs-access.js +parallel/test-fs-append-file-flush.js +parallel/test-fs-append-file.js +parallel/test-fs-append-file-sync.js +parallel/test-fs-assert-encoding-error.js +parallel/test-fs-buffer.js +parallel/test-fs-buffertype-writesync.js +parallel/test-fs-chmod.js +parallel/test-fs-chmod-mask.js +parallel/test-fs-chown-type-check.js +parallel/test-fs-close-errors.js +parallel/test-fs-close.js +parallel/test-fs-constants.js +parallel/test-fs-copyfile.js +parallel/test-fs-copyfile-respect-permissions.js +parallel/test-fs-empty-readStream.js +parallel/test-fs-error-messages.js +parallel/test-fs-exists.js +parallel/test-fs-existssync-false.js +parallel/test-fs-fchmod.js +parallel/test-fs-fchown.js +parallel/test-fs-filehandle.js +parallel/test-fs-filehandle-use-after-close.js +parallel/test-fs-fmap.js +parallel/test-fs-fsync.js +parallel/test-fs-lchmod.js +parallel/test-fs-lchown.js +parallel/test-fs-link.js +parallel/test-fs-long-path.js +parallel/test-fs-make-callback.js +parallel/test-fs-makeStatsCallback.js +parallel/test-fs-mkdir.js +parallel/test-fs-mkdir-mode-mask.js +parallel/test-fs-mkdir-recursive-eaccess.js +parallel/test-fs-mkdir-rmdir.js +parallel/test-fs-mkdtemp.js +parallel/test-fs-mkdtemp-prefix-check.js +parallel/test-fs-non-number-arguments-throw.js +parallel/test-fs-null-bytes.js +parallel/test-fs-opendir.js +parallel/test-fs-open-flags.js +parallel/test-fs-open.js +parallel/test-fs-open-mode-mask.js +parallel/test-fs-open-no-close.js +parallel/test-fs-open-numeric-flags.js +parallel/test-fs-operations-with-surrogate-pairs.js +parallel/test-fs-options-immutable.js +parallel/test-fs-promises-exists.js +parallel/test-fs-promises-file-handle-aggregate-errors.js +parallel/test-fs-promises-file-handle-append-file.js +parallel/test-fs-promises-file-handle-chmod.js +parallel/test-fs-promises-file-handle-close-errors.js +parallel/test-fs-promises-file-handle-close.js +parallel/test-fs-promises-file-handle-dispose.js +parallel/test-fs-promises-file-handle-op-errors.js +parallel/test-fs-promises-file-handle-readFile.js +parallel/test-fs-promises-file-handle-read.js +parallel/test-fs-promises-file-handle-read-worker.js +parallel/test-fs-promises-file-handle-stat.js +parallel/test-fs-promises-file-handle-stream.js +parallel/test-fs-promises-file-handle-sync.js +parallel/test-fs-promises-file-handle-truncate.js +parallel/test-fs-promises-file-handle-writeFile.js +parallel/test-fs-promises-file-handle-write.js +parallel/test-fs-promises.js +parallel/test-fs-promises-readfile-empty.js +parallel/test-fs-promises-readfile.js +parallel/test-fs-promises-readfile-with-fd.js +parallel/test-fs-promises-watch.js +parallel/test-fs-promises-writefile.js +parallel/test-fs-promises-writefile-typedarray.js +parallel/test-fs-promises-writefile-with-fd.js +parallel/test-fs-promises-write-optional-params.js +parallel/test-fs-promisified.js +parallel/test-fs-readdir-buffer.js +parallel/test-fs-readdir.js +parallel/test-fs-readdir-pipe.js +parallel/test-fs-readdir-recursive.js +parallel/test-fs-readdir-stack-overflow.js +parallel/test-fs-readdir-types.js +parallel/test-fs-readdir-types-symlinks.js +parallel/test-fs-readdir-ucs2.js +parallel/test-fs-read-empty-buffer.js +parallel/test-fs-read-file-assert-encoding.js +parallel/test-fs-readfile-empty.js +parallel/test-fs-readfile-eof.js +parallel/test-fs-readfile-error.js +parallel/test-fs-readfile-fd.js +parallel/test-fs-readfile-flags.js +parallel/test-fs-readfile.js +parallel/test-fs-readfile-pipe.js +parallel/test-fs-readfile-pipe-large.js +parallel/test-fs-readfilesync-enoent.js +parallel/test-fs-read-file-sync-hostname.js +parallel/test-fs-read-file-sync.js +parallel/test-fs-readfilesync-pipe-large.js +parallel/test-fs-readfile-unlink.js +parallel/test-fs-readfile-zero-byte-liar.js +parallel/test-fs-read.js +parallel/test-fs-readlink-type-check.js +parallel/test-fs-read-offset-null.js +parallel/test-fs-read-optional-params.js +parallel/test-fs-read-promises-optional-params.js +parallel/test-fs-read-stream-autoClose.js +parallel/test-fs-read-stream-concurrent-reads.js +parallel/test-fs-read-stream-double-close.js +parallel/test-fs-read-stream-encoding.js +parallel/test-fs-read-stream-err.js +parallel/test-fs-read-stream-fd.js +parallel/test-fs-read-stream-fd-leak.js +parallel/test-fs-read-stream-file-handle.js +parallel/test-fs-read-stream-inherit.js +parallel/test-fs-read-stream.js +parallel/test-fs-read-stream-patch-open.js +parallel/test-fs-read-stream-pos.js +parallel/test-fs-read-stream-resume.js +parallel/test-fs-read-stream-throw-type-error.js +parallel/test-fs-readSync-optional-params.js +parallel/test-fs-read-type.js +parallel/test-fs-readv.js +parallel/test-fs-readv-promises.js +parallel/test-fs-readv-promisify.js +parallel/test-fs-readv-sync.js +parallel/test-fs-ready-event-stream.js +parallel/test-fs-read-zero-length.js +parallel/test-fs-realpath-buffer-encoding.js +parallel/test-fs-realpath.js +parallel/test-fs-realpath-on-substed-drive.js +parallel/test-fs-realpath-pipe.js +parallel/test-fs-rename-type-check.js +parallel/test-fs-rmdir-recursive.js +parallel/test-fs-rmdir-recursive-sync-warns-not-found.js +parallel/test-fs-rmdir-recursive-sync-warns-on-file.js +parallel/test-fs-rmdir-recursive-throws-not-found.js +parallel/test-fs-rmdir-recursive-throws-on-file.js +parallel/test-fs-rmdir-recursive-warns-not-found.js +parallel/test-fs-rmdir-recursive-warns-on-file.js +parallel/test-fs-rmdir-type-check.js +parallel/test-fs-rm.js +parallel/test-fs-sir-writes-alot.js +parallel/test-fs-stat-bigint.js +parallel/test-fs-statfs.js +parallel/test-fs-stat.js +parallel/test-fs-stream-construct-compat-error-read.js +parallel/test-fs-stream-construct-compat-error-write.js +parallel/test-fs-stream-construct-compat-graceful-fs.js +parallel/test-fs-stream-construct-compat-old-node.js +parallel/test-fs-stream-destroy-emit-error.js +parallel/test-fs-stream-double-close.js +parallel/test-fs-stream-fs-options.js +parallel/test-fs-stream-options.js +parallel/test-fs-symlink-buffer-path.js +parallel/test-fs-symlink-dir.js +parallel/test-fs-symlink-dir-junction.js +parallel/test-fs-symlink-dir-junction-relative.js +parallel/test-fs-symlink.js +parallel/test-fs-symlink-longpath.js +parallel/test-fs-sync-fd-leak.js +parallel/test-fs-syncwritestream.js +parallel/test-fs-timestamp-parsing-error.js +parallel/test-fs-truncate-clear-file-zero.js +parallel/test-fs-truncate-fd.js +parallel/test-fs-truncate.js +parallel/test-fs-truncate-sync.js +parallel/test-fs-unlink-type-check.js +parallel/test-fs-utils-get-dirents.js +parallel/test-fs-util-validateoffsetlength.js +parallel/test-fs-utimes.js +# Test disabled on 3.18.2025 as: +# utime-y2K38 has issues because i686 can't handle dates past 2038 +# and the support for this arch is no longer required +parallel/test-fs-utimes-y2K38.js i686 +parallel/test-fs-watch-abort-signal.js +parallel/test-fs-watch-close-when-destroyed.js +parallel/test-fs-watch-encoding.js +parallel/test-fs-watch-enoent.js +parallel/test-fs-watchfile-bigint.js +parallel/test-fs-watch-file-enoent-after-deletion.js +parallel/test-fs-watchfile.js +parallel/test-fs-watchfile-ref-unref.js +parallel/test-fs-watch.js +parallel/test-fs-watch-recursive-add-file.js +parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js +parallel/test-fs-watch-recursive-add-file-to-new-folder.js +parallel/test-fs-watch-recursive-add-file-with-url.js +parallel/test-fs-watch-recursive-add-folder.js +parallel/test-fs-watch-recursive-assert-leaks.js +parallel/test-fs-watch-recursive-delete.js +parallel/test-fs-watch-recursive-linux-parallel-remove.js +parallel/test-fs-watch-recursive-promise.js +parallel/test-fs-watch-recursive-symlink.js +parallel/test-fs-watch-recursive-sync-write.js +parallel/test-fs-watch-recursive-update-file.js +parallel/test-fs-watch-recursive-validate.js +parallel/test-fs-watch-recursive-watch-file.js +parallel/test-fs-watch-ref-unref.js +parallel/test-fs-watch-stop-async.js +parallel/test-fs-watch-stop-sync.js +parallel/test-fs-whatwg-url.js +parallel/test-fs-write-buffer.js +parallel/test-fs-write-buffer-large.js +parallel/test-fs-write-file-buffer.js +parallel/test-fs-write-file-flush.js +parallel/test-fs-write-file-invalid-path.js +parallel/test-fs-write-file.js +parallel/test-fs-write-file-sync.js +parallel/test-fs-write-file-typedarrays.js +parallel/test-fs-writefile-with-fd.js +parallel/test-fs-write.js +parallel/test-fs-write-negativeoffset.js +parallel/test-fs-write-no-fd.js +parallel/test-fs-write-optional-params.js +parallel/test-fs-write-reuse-callback.js +parallel/test-fs-write-sigxfsz.js +parallel/test-fs-write-stream-autoclose-option.js +parallel/test-fs-write-stream-change-open.js +parallel/test-fs-write-stream-close-without-callback.js +parallel/test-fs-write-stream-double-close.js +parallel/test-fs-write-stream-encoding.js +parallel/test-fs-write-stream-end.js +parallel/test-fs-write-stream-err.js +parallel/test-fs-write-stream-file-handle-2.js +parallel/test-fs-write-stream-file-handle.js +parallel/test-fs-write-stream-flush.js +parallel/test-fs-write-stream-fs.js +parallel/test-fs-write-stream.js +parallel/test-fs-writestream-open-write.js +parallel/test-fs-write-stream-patch-open.js +parallel/test-fs-write-stream-throw-type-error.js +parallel/test-fs-write-sync.js +parallel/test-fs-write-sync-optional-params.js +parallel/test-fs-writev.js +parallel/test-fs-writev-promises.js +parallel/test-fs-writev-sync.js +parallel/test-gc-http-client-connaborted.js +parallel/test-gc-net-timeout.js +parallel/test-gc-tls-external-memory.js +parallel/test-global-console-exists.js +parallel/test-global-customevent-disabled.js +parallel/test-global-customevent.js +parallel/test-global-domexception.js +parallel/test-global-encoder.js +parallel/test-global.js +parallel/test-global-setters.js +parallel/test-global-webcrypto-classes.js +parallel/test-global-webcrypto-disbled.js +parallel/test-global-webcrypto.js +parallel/test-global-webstreams.js +parallel/test-h2-large-header-cause-client-to-hangup.js +parallel/test-h2leak-destroy-session-on-socket-ended.js +parallel/test-handle-wrap-close-abort.js +parallel/test-handle-wrap-hasref.js +parallel/test-heapdump-async-hooks-init-promise.js +parallel/test-heap-prof-basic.js +parallel/test-heap-prof-dir-absolute.js +parallel/test-heap-prof-dir-name.js +parallel/test-heap-prof-dir-relative.js +parallel/test-heap-prof-exec-argv.js +parallel/test-heap-prof-exit.js +parallel/test-heap-prof-interval.js +parallel/test-heap-prof-invalid-args.js +parallel/test-heap-prof-loop-drained.js +parallel/test-heap-prof-name.js +parallel/test-heap-prof-sigint.js +parallel/test-heapsnapshot-near-heap-limit-by-api-in-worker.js +parallel/test-heapsnapshot-near-heap-limit-worker.js +parallel/test-http-1.0.js +parallel/test-http-1.0-keep-alive.js +parallel/test-http2-allow-http1.js +parallel/test-http2-alpn.js +parallel/test-http2-altsvc.js +parallel/test-http2-async-local-storage.js +parallel/test-http2-autoselect-protocol.js +parallel/test-http2-backpressure.js +parallel/test-http2-binding.js +parallel/test-http2-buffersize.js +parallel/test-http2-byteswritten-server.js +parallel/test-http2-cancel-while-client-reading.js +parallel/test-http2-capture-rejection.js +parallel/test-http2-clean-output.js +parallel/test-http2-client-connection-tunnelling.js +parallel/test-http2-client-data-end.js +parallel/test-http2-client-destroy.js +parallel/test-http2-client-http1-server.js +parallel/test-http2-client-jsstream-destroy.js +parallel/test-http2-client-onconnect-errors.js +parallel/test-http2-client-port-80.js +parallel/test-http2-client-priority-before-connect.js +parallel/test-http2-client-promisify-connect-error.js +parallel/test-http2-client-promisify-connect.js +parallel/test-http2-client-proxy-over-http2.js +parallel/test-http2-client-request-listeners-warning.js +parallel/test-http2-client-request-options-errors.js +parallel/test-http2-client-rststream-before-connect.js +parallel/test-http2-client-setLocalWindowSize.js +parallel/test-http2-client-setNextStreamID-errors.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-client-set-priority.js +parallel/test-http2-client-settings-before-connect.js +parallel/test-http2-client-shutdown-before-connect.js +parallel/test-http2-client-socket-destroy.js +parallel/test-http2-client-stream-destroy-before-connect.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-client-unescaped-path.js +parallel/test-http2-client-upload.js +parallel/test-http2-client-upload-reject.js +parallel/test-http2-client-write-before-connect.js +parallel/test-http2-client-write-empty-string.js +parallel/test-http2-close-while-writing.js +parallel/test-http2-compat-aborted.js +parallel/test-http2-compat-client-upload-reject.js +parallel/test-http2-compat-errors.js +parallel/test-http2-compat-expect-continue-check.js +parallel/test-http2-compat-expect-continue.js +parallel/test-http2-compat-expect-handling.js +parallel/test-http2-compat-method-connect.js +parallel/test-http2-compat-serverrequest-end.js +parallel/test-http2-compat-serverrequest-headers.js +parallel/test-http2-compat-serverrequest-host.js +parallel/test-http2-compat-serverrequest.js +parallel/test-http2-compat-serverrequest-pause.js +parallel/test-http2-compat-serverrequest-pipe.js +parallel/test-http2-compat-serverrequest-settimeout.js +parallel/test-http2-compat-serverrequest-trailers.js +parallel/test-http2-compat-serverresponse-close.js +parallel/test-http2-compat-serverresponse-createpushresponse.js +parallel/test-http2-compat-serverresponse-destroy.js +parallel/test-http2-compat-serverresponse-drain.js +parallel/test-http2-compat-serverresponse-end-after-statuses-without-body.js +parallel/test-http2-compat-serverresponse-end.js +parallel/test-http2-compat-serverresponse-finished.js +parallel/test-http2-compat-serverresponse-flushheaders.js +parallel/test-http2-compat-serverresponse-headers-after-destroy.js +parallel/test-http2-compat-serverresponse-headers.js +parallel/test-http2-compat-serverresponse-headers-send-date.js +parallel/test-http2-compat-serverresponse.js +parallel/test-http2-compat-serverresponse-settimeout.js +parallel/test-http2-compat-serverresponse-statuscode.js +parallel/test-http2-compat-serverresponse-statusmessage.js +parallel/test-http2-compat-serverresponse-statusmessage-property.js +parallel/test-http2-compat-serverresponse-statusmessage-property-set.js +parallel/test-http2-compat-serverresponse-trailers.js +parallel/test-http2-compat-serverresponse-writehead-array.js +parallel/test-http2-compat-serverresponse-writehead.js +parallel/test-http2-compat-serverresponse-write.js +parallel/test-http2-compat-short-stream-client-server.js +parallel/test-http2-compat-socket-destroy-delayed.js +parallel/test-http2-compat-socket.js +parallel/test-http2-compat-socket-set.js +parallel/test-http2-compat-write-early-hints-invalid-argument-type.js +parallel/test-http2-compat-write-early-hints-invalid-argument-value.js +parallel/test-http2-compat-write-early-hints.js +parallel/test-http2-compat-write-head-destroyed.js +parallel/test-http2-connect.js +parallel/test-http2-connect-method-extended-cant-turn-off.js +parallel/test-http2-connect-method-extended.js +parallel/test-http2-connect-method.js +parallel/test-http2-connect-options.js +parallel/test-http2-connect-tls-with-delay.js +parallel/test-http2-cookies.js +parallel/test-http2-create-client-connect.js +parallel/test-http2-create-client-secure-session.js +parallel/test-http2-create-client-session.js +parallel/test-http2-createsecureserver-options.js +parallel/test-http2-createserver-options.js +parallel/test-http2-createwritereq.js +parallel/test-http2-date-header.js +parallel/test-http2-debug.js +parallel/test-http2-destroy-after-write.js +parallel/test-http2-dont-lose-data.js +parallel/test-http2-dont-override.js +parallel/test-http2-empty-frame-without-eof.js +parallel/test-http2-endafterheaders.js +parallel/test-http2-error-order.js +parallel/test-http2-exceeds-server-trailer-size.js +parallel/test-http2-forget-closed-streams.js +parallel/test-http2-generic-streams.js +parallel/test-http2-generic-streams-sendfile.js +parallel/test-http2-getpackedsettings.js +parallel/test-http2-goaway-delayed-request.js +parallel/test-http2-goaway-opaquedata.js +parallel/test-http2-head-request.js +parallel/test-http2-https-fallback-http-server-options.js +parallel/test-http2-https-fallback.js +parallel/test-http2-info-headers-errors.js +parallel/test-http2-info-headers.js +parallel/test-http2-invalidargtypes-errors.js +parallel/test-http2-invalidheaderfield.js +parallel/test-http2-invalidheaderfields-client.js +parallel/test-http2-ip-address-host.js +parallel/test-http2-large-write-close.js +parallel/test-http2-large-write-destroy.js +parallel/test-http2-large-write-multiple-requests.js +parallel/test-http2-large-writes-session-memory-leak.js +parallel/test-http2-malformed-altsvc.js +parallel/test-http2-many-writes-and-destroy.js +parallel/test-http2-max-concurrent-streams.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-max-invalid-frames.js +parallel/test-http2-max-session-memory-leak.js +parallel/test-http2-max-settings.js +parallel/test-http2-methods.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-misbehaving-flow-control.js +# parallel/test-http2-misbehaving-flow-control-paused.js +parallel/test-http2-misbehaving-multiplex.js +parallel/test-http2-misc-util.js +parallel/test-http2-misused-pseudoheaders.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-multi-content-length.js +parallel/test-http2-multiheaders.js +parallel/test-http2-multiheaders-raw.js +parallel/test-http2-multiplex.js +parallel/test-http2-multistream-destroy-on-read-tls.js +parallel/test-http2-no-more-streams.js +parallel/test-http2-no-wanttrailers-listener.js +parallel/test-http2-onping.js +parallel/test-http2-options-max-headers-block-length.js +parallel/test-http2-options-max-headers-exceeds-nghttp2.js +parallel/test-http2-options-max-reserved-streams.js +parallel/test-http2-options-server-request.js +parallel/test-http2-options-server-response.js +parallel/test-http2-origin.js +parallel/test-http2-pack-end-stream-flag.js +parallel/test-http2-padding-aligned.js +parallel/test-http2-perf_hooks.js +parallel/test-http2-perform-server-handshake.js +parallel/test-http2-ping.js +parallel/test-http2-ping-settings-heapdump.js +parallel/test-http2-ping-unsolicited-ack.js +parallel/test-http2-pipe.js +parallel/test-http2-pipe-named-pipe.js +parallel/test-http2-priority-cycle-.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-priority-event.js +parallel/test-http2-propagate-session-destroy-code.js +parallel/test-http2-removed-header-stays-removed.js +parallel/test-http2-request-remove-connect-listener.js +parallel/test-http2-request-response-proto.js +parallel/test-http2-res-corked.js +# disabled on 25.03.26, see https://github.com/nodejs/node/issues/60661 +# parallel/test-http2-reset-flood.js +parallel/test-http2-respond-errors.js +parallel/test-http2-respond-file-204.js +parallel/test-http2-respond-file-304.js +parallel/test-http2-respond-file-404.js +parallel/test-http2-respond-file-compat.js +parallel/test-http2-respond-file-error-dir.js +parallel/test-http2-respond-file-error-pipe-offset.js +parallel/test-http2-respond-file-errors.js +parallel/test-http2-respond-file-fd-errors.js +parallel/test-http2-respond-file-fd-invalid.js +parallel/test-http2-respond-file-fd.js +parallel/test-http2-respond-file-fd-range.js +parallel/test-http2-respond-file-filehandle.js +parallel/test-http2-respond-file.js +parallel/test-http2-respond-file-push.js +parallel/test-http2-respond-file-range.js +parallel/test-http2-respond-file-with-pipe.js +parallel/test-http2-respond-nghttperrors.js +parallel/test-http2-respond-no-data.js +parallel/test-http2-respond-with-fd-errors.js +parallel/test-http2-respond-with-file-connection-abort.js +parallel/test-http2-response-splitting.js +parallel/test-http2-res-writable-properties.js +parallel/test-http2-sensitive-headers.js +parallel/test-http2-sent-headers.js +parallel/test-http2-serve-file.js +parallel/test-http2-server-async-dispose.js +parallel/test-http2-server-close-callback.js +parallel/test-http2-server-errors.js +parallel/test-http2-server-http1-client.js +parallel/test-http2-server-push-disabled.js +parallel/test-http2-server-push-stream-errors-args.js +parallel/test-http2-server-push-stream-errors.js +parallel/test-http2-server-push-stream-head.js +parallel/test-http2-server-push-stream.js +parallel/test-http2-server-rst-before-respond.js +parallel/test-http2-server-rst-stream.js +parallel/test-http2-server-session-destroy.js +parallel/test-http2-server-sessionerror.js +parallel/test-http2-server-set-header.js +parallel/test-http2-server-setLocalWindowSize.js +parallel/test-http2-server-settimeout-no-callback.js +parallel/test-http2-server-shutdown-before-respond.js +parallel/test-http2-server-shutdown-options-errors.js +parallel/test-http2-server-shutdown-redundant.js +parallel/test-http2-server-socket-destroy.js +parallel/test-http2-server-startup.js +parallel/test-http2-server-stream-session-destroy.js +parallel/test-http2-server-timeout.js +parallel/test-http2-server-unknown-protocol.js +parallel/test-http2-session-gc-while-write-scheduled.js +parallel/test-http2-session-settings.js +parallel/test-http2-session-stream-state.js +parallel/test-http2-session-timeout.js +parallel/test-http2-session-unref.js +parallel/test-http2-settings-unsolicited-ack.js +parallel/test-http2-short-stream-client-server.js +parallel/test-http2-single-headers.js +parallel/test-http2-socket-close.js +parallel/test-http2-socket-proxy-handler-for-has.js +parallel/test-http2-socket-proxy.js +parallel/test-http2-status-code-invalid.js +parallel/test-http2-status-code.js +parallel/test-http2-stream-client.js +parallel/test-http2-stream-destroy-event-order.js +parallel/test-http2-stream-removelisteners-after-close.js +parallel/test-http2-timeouts.js +parallel/test-http2-tls-disconnect.js +parallel/test-http2-too-large-headers.js +parallel/test-http2-too-many-headers.js +parallel/test-http2-too-many-settings.js +parallel/test-http2-too-many-streams.js +parallel/test-http2-trailers-after-session-close.js +parallel/test-http2-trailers.js +parallel/test-http2-unbound-socket-proxy.js +parallel/test-http2-update-settings.js +parallel/test-http2-util-asserts.js +parallel/test-http2-util-assert-valid-pseudoheader.js +parallel/test-http2-util-headers-list.js +parallel/test-http2-util-nghttp2error.js +parallel/test-http2-util-update-options-buffer.js +parallel/test-http2-window-size.js +parallel/test-http2-write-callbacks.js +parallel/test-http2-write-empty-string.js +parallel/test-http2-write-finishes-after-stream-destroy.js +parallel/test-http2-zero-length-header.js +parallel/test-http2-zero-length-write.js +parallel/test-http-abort-before-end.js +parallel/test-http-abort-client.js +parallel/test-http-aborted.js +parallel/test-http-abort-queued.js +parallel/test-http-abort-stream-end.js +parallel/test-http-addrequest-localaddress.js +parallel/test-http-after-connect.js +parallel/test-http-agent-abort-controller.js +parallel/test-http-agent-close.js +parallel/test-http-agent-destroyed-socket.js +parallel/test-http-agent-domain-reused-gc.js +parallel/test-http-agent-error-on-idle.js +parallel/test-http-agent-false.js +parallel/test-http-agent-getname.js +parallel/test-http-agent.js +parallel/test-http-agent-keepalive-delay.js +parallel/test-http-agent-keepalive.js +parallel/test-http-agent-maxsockets.js +parallel/test-http-agent-maxsockets-respected.js +parallel/test-http-agent-maxtotalsockets.js +parallel/test-http-agent-no-protocol.js +parallel/test-http-agent-null.js +parallel/test-http-agent-remove.js +parallel/test-http-agent-reuse-drained-socket-only.js +parallel/test-http-agent-scheduling.js +parallel/test-http-agent-timeout.js +parallel/test-http-agent-timeout-option.js +parallel/test-http-agent-uninitialized.js +parallel/test-http-agent-uninitialized-with-handle.js +parallel/test-http-allow-content-length-304.js +parallel/test-http-allow-req-after-204-res.js +parallel/test-http-automatic-headers.js +parallel/test-http-autoselectfamily.js +parallel/test-http-bind-twice.js +parallel/test-http-blank-header.js +parallel/test-http-buffer-sanity.js +parallel/test-http-byteswritten.js +parallel/test-http-catch-uncaughtexception.js +parallel/test-http-chunked-304.js +parallel/test-http-chunked.js +parallel/test-http-chunked-smuggling.js +parallel/test-http-chunk-extensions-limit.js +parallel/test-http-chunk-problem.js +parallel/test-http-client-abort2.js +parallel/test-http-client-abort3.js +parallel/test-http-client-abort-destroy.js +parallel/test-http-client-aborted-event.js +parallel/test-http-client-abort-event.js +parallel/test-http-client-abort.js +parallel/test-http-client-abort-keep-alive-destroy-res.js +parallel/test-http-client-abort-keep-alive-queued-tcp-socket.js +parallel/test-http-client-abort-keep-alive-queued-unix-socket.js +parallel/test-http-client-abort-no-agent.js +parallel/test-http-client-abort-response-event.js +parallel/test-http-client-abort-unix-socket.js +parallel/test-http-client-agent-abort-close-event.js +parallel/test-http-client-agent-end-close-event.js +parallel/test-http-client-agent.js +parallel/test-http-client-check-http-token.js +parallel/test-http-client-close-event.js +parallel/test-http-client-close-with-default-agent.js +parallel/test-http-client-default-headers-exist.js +parallel/test-http-client-defaults.js +parallel/test-http-client-encoding.js +parallel/test-http-client-error-rawbytes.js +parallel/test-http-client-finished.js +parallel/test-http-client-get-url.js +parallel/test-http-client-headers-array.js +parallel/test-http-client-headers-host-array.js +parallel/test-http-client-immediate-error.js +parallel/test-http-client-incomingmessage-destroy.js +parallel/test-http-client-input-function.js +parallel/test-http-client-insecure-http-parser-error.js +parallel/test-http-client-invalid-path.js +parallel/test-http-client-keep-alive-hint.js +parallel/test-http-client-keep-alive-release-before-finish.js +parallel/test-http-client-override-global-agent.js +parallel/test-http-client-parse-error.js +parallel/test-http-client-pipe-end.js +parallel/test-http-client-race-2.js +parallel/test-http-client-race.js +parallel/test-http-client-readable.js +parallel/test-http-client-read-in-error.js +parallel/test-http-client-reject-chunked-with-content-length.js +parallel/test-http-client-reject-cr-no-lf.js +parallel/test-http-client-reject-unexpected-agent.js +parallel/test-http-client-req-error-dont-double-fire.js +parallel/test-http-client-request-options.js +parallel/test-http-client-res-destroyed.js +parallel/test-http-client-response-domain.js +parallel/test-http-client-response-timeout.js +parallel/test-http-client-set-timeout-after-end.js +parallel/test-http-client-set-timeout.js +parallel/test-http-client-spurious-aborted.js +parallel/test-http-client-timeout-agent.js +parallel/test-http-client-timeout-connect-listener.js +parallel/test-http-client-timeout-event.js +parallel/test-http-client-timeout.js +parallel/test-http-client-timeout-on-connect.js +parallel/test-http-client-timeout-option.js +parallel/test-http-client-timeout-option-listeners.js +parallel/test-http-client-timeout-option-with-agent.js +parallel/test-http-client-timeout-with-data.js +parallel/test-http-client-unescaped-path.js +parallel/test-http-client-upload-buf.js +parallel/test-http-client-upload.js +parallel/test-http-client-with-create-connection.js +parallel/test-http-common.js +parallel/test-http-connect.js +parallel/test-http-connect-req-res.js +parallel/test-http-conn-reset.js +parallel/test-http-contentLength0.js +parallel/test-http-content-length.js +parallel/test-http-content-length-mismatch.js +parallel/test-http-correct-hostname.js +parallel/test-http-createConnection.js +parallel/test-http-date-header.js +parallel/test-http-debug.js +parallel/test-http-decoded-auth.js +parallel/test-http-default-encoding.js +parallel/test-http-default-port.js +parallel/test-http-destroyed-socket-write2.js +parallel/test-http-dns-error.js +parallel/test-http-dont-set-default-headers.js +parallel/test-http-dont-set-default-headers-with-set-header.js +parallel/test-http-dont-set-default-headers-with-setHost.js +parallel/test-http-double-content-length.js +parallel/test-http-dummy-characters-smuggling.js +parallel/test-http-dump-req-when-res-ends.js +parallel/test-http-early-hints-invalid-argument.js +parallel/test-http-early-hints.js +parallel/test-http-end-throw-socket-handling.js +parallel/test-http-eof-on-connect.js +parallel/test-http-exceptions.js +parallel/test-http-expect-continue.js +parallel/test-http-expect-handling.js +parallel/test-http-extra-response.js +parallel/test-http-flush-headers.js +parallel/test-http-flush-response-headers.js +parallel/test-http-full-response.js +parallel/test-http-generic-streams.js +parallel/test-http-get-pipeline-problem.js +parallel/test-http-header-badrequest.js +parallel/test-http-header-obstext.js +parallel/test-http-header-overflow.js +parallel/test-http-header-owstext.js +parallel/test-http-header-read.js +parallel/test-http-header-validators.js +parallel/test-http-head-request.js +parallel/test-http-head-response-has-no-body-end-implicit-headers.js +parallel/test-http-head-response-has-no-body-end.js +parallel/test-http-head-response-has-no-body.js +parallel/test-http-head-throw-on-response-body-write.js +parallel/test-http-hex-write.js +parallel/test-http-highwatermark.js +parallel/test-http-host-header-ipv6-fail.js +parallel/test-http-host-headers.js +parallel/test-http-hostname-typechecking.js +parallel/test-http-import-websocket.js +parallel/test-http-incoming-matchKnownFields.js +parallel/test-http-incoming-message-connection-setter.js +parallel/test-http-incoming-message-destroy.js +parallel/test-http-incoming-message-options.js +parallel/test-http-incoming-pipelined-socket-destroy.js +parallel/test-http-information-headers.js +parallel/test-http-information-processing.js +parallel/test-http-insecure-parser.js +parallel/test-http-insecure-parser-per-stream.js +parallel/test-http-invalidheaderfield2.js +parallel/test-http-invalidheaderfield.js +parallel/test-http-invalid-path-chars.js +parallel/test-http-invalid-te.js +parallel/test-http-invalid-urls.js +parallel/test-http.js +parallel/test-http-keepalive-client.js +parallel/test-http-keep-alive-close-on-header.js +parallel/test-http-keep-alive-drop-requests.js +parallel/test-http-keepalive-free.js +parallel/test-http-keep-alive.js +parallel/test-http-keep-alive-max-requests.js +parallel/test-http-keepalive-override.js +parallel/test-http-keep-alive-pipeline-max-requests.js +parallel/test-http-keepalive-request.js +parallel/test-http-keep-alive-timeout-custom.js +parallel/test-http-keep-alive-timeout.js +parallel/test-http-keep-alive-timeout-race-condition.js +parallel/test-http-listening.js +parallel/test-http-localaddress-bind-error.js +parallel/test-http-localaddress.js +parallel/test-http-malformed-request.js +parallel/test-http-many-ended-pipelines.js +parallel/test-http-max-headers-count.js +parallel/test-http-max-header-size.js +parallel/test-http-max-header-size-per-stream.js +parallel/test-http-max-http-headers.js +parallel/test-http-max-sockets.js +parallel/test-http-methods.js +parallel/test-http-missing-header-separator-cr.js +parallel/test-http-missing-header-separator-lf.js +parallel/test-http-multi-line-headers.js +parallel/test-http-multiple-headers.js +parallel/test-http-mutable-headers.js +parallel/test-http-no-content-length.js +parallel/test-http-nodelay.js +parallel/test-http-no-read-no-dump.js +parallel/test-http-outgoing-buffer.js +parallel/test-http-outgoing-destroyed.js +parallel/test-http-outgoing-destroy.js +parallel/test-http-outgoing-end-cork.js +parallel/test-http-outgoing-end-multiple.js +parallel/test-http-outgoing-end-types.js +parallel/test-http-outgoing-finished.js +parallel/test-http-outgoing-finish.js +parallel/test-http-outgoing-finish-writable.js +parallel/test-http-outgoing-first-chunk-singlebyte-encoding.js +parallel/test-http-outgoing-internal-headernames-getter.js +parallel/test-http-outgoing-internal-headernames-setter.js +parallel/test-http-outgoing-internal-headers.js +parallel/test-http-outgoing-message-capture-rejection.js +parallel/test-http-outgoing-message-inheritance.js +parallel/test-http-outgoing-message-write-callback.js +parallel/test-http-outgoing-properties.js +parallel/test-http-outgoing-proto.js +parallel/test-http-outgoing-renderHeaders.js +parallel/test-http-outgoing-settimeout.js +parallel/test-http-outgoing-writableFinished.js +parallel/test-http-outgoing-write-types.js +parallel/test-http-parser-bad-ref.js +parallel/test-http-parser-finish-error.js +parallel/test-http-parser-freed-before-upgrade.js +parallel/test-http-parser-free.js +parallel/test-http-parser.js +parallel/test-http-parser-lazy-loaded.js +parallel/test-http-parser-memory-retention.js +parallel/test-http-parser-multiple-execute.js +parallel/test-http-parser-timeout-reset.js +parallel/test-http-pause.js +parallel/test-http-pause-no-dump.js +parallel/test-http-pause-resume-one-end.js +parallel/test-http-perf_hooks.js +parallel/test-http-pipe-fs.js +parallel/test-http-pipeline-assertionerror-finish.js +parallel/test-http-pipeline-flood.js +parallel/test-http-pipeline-requests-connection-leak.js +parallel/test-http-pipeline-socket-parser-typeerror.js +parallel/test-http-proxy.js +parallel/test-http-raw-headers.js +parallel/test-http-readable-data-event.js +parallel/test-http-remove-connection-header-persists-connection.js +parallel/test-http-remove-header-stays-removed.js +parallel/test-http-req-close-robust-from-tampering.js +parallel/test-http-req-res-close.js +parallel/test-http-request-agent.js +parallel/test-http-request-arguments.js +parallel/test-http-request-dont-override-options.js +parallel/test-http-request-end.js +parallel/test-http-request-end-twice.js +parallel/test-http-request-host-header.js +parallel/test-http-request-invalid-method-error.js +parallel/test-http-request-join-authorization-headers.js +parallel/test-http-request-large-payload.js +parallel/test-http-request-method-delete-payload.js +parallel/test-http-request-methods.js +parallel/test-http-request-smuggling-content-length.js +parallel/test-http-response-add-header-after-sent.js +parallel/test-http-response-close.js +parallel/test-http-response-cork.js +parallel/test-http-response-multi-content-length.js +parallel/test-http-response-multiheaders.js +parallel/test-http-response-no-headers.js +parallel/test-http-response-readable.js +parallel/test-http-response-remove-header-after-sent.js +parallel/test-http-response-setheaders.js +parallel/test-http-response-splitting.js +parallel/test-http-response-statuscode.js +parallel/test-http-response-status-message.js +parallel/test-http-response-writehead-returns-this.js +parallel/test-http-res-write-after-end.js +parallel/test-http-res-write-end-dont-take-array.js +parallel/test-https-abortcontroller.js +parallel/test-https-agent-abort-controller.js +parallel/test-https-agent-constructor.js +parallel/test-https-agent-create-connection.js +parallel/test-https-agent-disable-session-reuse.js +parallel/test-https-agent-getname.js +parallel/test-https-agent.js +parallel/test-https-agent-keylog.js +parallel/test-https-agent-servername.js +parallel/test-https-agent-session-eviction.js +parallel/test-https-agent-session-injection.js +parallel/test-https-agent-session-reuse.js +parallel/test-https-agent-sni.js +parallel/test-https-agent-sockets-leak.js +parallel/test-https-agent-unref-socket.js +parallel/test-http-same-map.js +parallel/test-https-argument-of-creating.js +parallel/test-https-autoselectfamily.js +parallel/test-https-byteswritten.js +parallel/test-https-client-checkServerIdentity.js +parallel/test-https-client-get-url.js +parallel/test-https-client-override-global-agent.js +parallel/test-https-client-reject.js +parallel/test-https-client-renegotiation-limit.js +parallel/test-https-client-resume.js +parallel/test-https-close.js +parallel/test-https-connect-address-family.js +parallel/test-https-connecting-to-http.js +parallel/test-https-drain.js +parallel/test-https-eof-for-eom.js +parallel/test-http-server-async-dispose.js +parallel/test-http-server-capture-rejections.js +parallel/test-http-server-clear-timer.js +parallel/test-http-server-client-error.js +parallel/test-http-server-close-all.js +parallel/test-http-server-close-destroy-timeout.js +parallel/test-http-server-close-idle.js +parallel/test-http-server-close-idle-wait-response.js +parallel/test-http-server-connection-list-when-close.js +parallel/test-http-server-connections-checking-leak.js +parallel/test-http-server-consumed-timeout.js +parallel/test-http-server-de-chunked-trailer.js +parallel/test-http-server-delete-parser.js +parallel/test-http-server-destroy-socket-on-client-error.js +parallel/test-http-server-headers-timeout-delayed-headers.js +parallel/test-http-server-headers-timeout-interrupted-headers.js +parallel/test-http-server-headers-timeout-keepalive.js +parallel/test-http-server-headers-timeout-pipelining.js +parallel/test-http-server-incomingmessage-destroy.js +parallel/test-http-server.js +parallel/test-http-server-keep-alive-defaults.js +parallel/test-http-server-keepalive-end.js +parallel/test-http-server-keep-alive-max-requests-null.js +parallel/test-http-server-keepalive-req-gc.js +parallel/test-http-server-keep-alive-timeout.js +parallel/test-http-server-method.query.js +parallel/test-http-server-multiheaders2.js +parallel/test-http-server-multiheaders.js +parallel/test-http-server-multiple-client-error.js +parallel/test-http-server-non-utf8-header.js +parallel/test-http-server-options-highwatermark.js +parallel/test-http-server-options-incoming-message.js +parallel/test-http-server-options-server-response.js +parallel/test-http-server-reject-chunked-with-content-length.js +parallel/test-http-server-reject-cr-no-lf.js +parallel/test-http-server-request-timeout-delayed-body.js +parallel/test-http-server-request-timeout-delayed-headers.js +parallel/test-http-server-request-timeout-interrupted-body.js +parallel/test-http-server-request-timeout-interrupted-headers.js +parallel/test-http-server-request-timeout-keepalive.js +parallel/test-http-server-request-timeout-pipelining.js +parallel/test-http-server-request-timeout-upgrade.js +parallel/test-http-server-response-standalone.js +parallel/test-http-server-stale-close.js +parallel/test-http-server-timeouts-validation.js +parallel/test-http-server-unconsume-consume.js +parallel/test-http-server-unconsume.js +parallel/test-http-server-write-after-end.js +parallel/test-http-server-write-end-after-end.js +parallel/test-http-set-cookies.js +parallel/test-http-set-header-chain.js +parallel/test-http-set-max-idle-http-parser.js +parallel/test-http-set-timeout.js +parallel/test-http-set-timeout-server.js +parallel/test-http-set-trailers.js +parallel/test-https-foafssl.js +parallel/test-https-host-headers.js +parallel/test-http-should-keep-alive.js +parallel/test-https-hwm.js +parallel/test-https-insecure-parse-per-stream.js +parallel/test-https-keep-alive-drop-requests.js +parallel/test-https-localaddress-bind-error.js +parallel/test-https-localaddress.js +parallel/test-https-max-headers-count.js +parallel/test-https-max-header-size-per-stream.js +parallel/test-http-socket-encoding-error.js +parallel/test-http-socket-error-listeners.js +parallel/test-https-options-boolean-check.js +parallel/test-https-pfx.js +parallel/test-https-request-arguments.js +parallel/test-https-resume-after-renew.js +parallel/test-https-selfsigned-no-keycertsign-no-crash.js +parallel/test-https-server-async-dispose.js +parallel/test-https-server-close-all.js +parallel/test-https-server-close-destroy-timeout.js +parallel/test-https-server-close-idle.js +parallel/test-https-server-connections-checking-leak.js +parallel/test-https-server-headers-timeout.js +parallel/test-https-server-options-incoming-message.js +parallel/test-https-server-options-server-response.js +parallel/test-https-server-request-timeout.js +parallel/test-https-set-timeout-server.js +parallel/test-https-simple.js +parallel/test-https-socket-options.js +parallel/test-https-strict.js +parallel/test-http-status-code.js +parallel/test-http-status-message.js +parallel/test-http-status-reason-invalid-chars.js +parallel/test-https-timeout.js +parallel/test-https-timeout-server-2.js +parallel/test-https-timeout-server.js +parallel/test-https-truncate.js +parallel/test-https-unix-socket-self-signed.js +parallel/test-http-sync-write-error-during-continue.js +parallel/test-http-timeout-client-warning.js +parallel/test-http-timeout.js +parallel/test-http-timeout-overflow.js +parallel/test-http-transfer-encoding-repeated-chunked.js +parallel/test-http-transfer-encoding-smuggling.js +parallel/test-http-uncaught-from-request-callback.js +parallel/test-http-unix-socket.js +parallel/test-http-unix-socket-keep-alive.js +parallel/test-http-upgrade-advertise.js +parallel/test-http-upgrade-agent.js +parallel/test-http-upgrade-binary.js +parallel/test-http-upgrade-client2.js +parallel/test-http-upgrade-client.js +parallel/test-http-upgrade-reconsume-stream.js +parallel/test-http-upgrade-server2.js +parallel/test-http-upgrade-server.js +parallel/test-http-url.parse-auth.js +parallel/test-http-url.parse-auth-with-header-in-request.js +parallel/test-http-url.parse-basic.js +parallel/test-http-url.parse-https.request.js +parallel/test-http-url.parse-only-support-http-https-protocol.js +parallel/test-http-url.parse-path.js +parallel/test-http-url.parse-post.js +parallel/test-http-url.parse-search.js +parallel/test-http-wget.js +parallel/test-http-writable-true-after-close.js +parallel/test-http-write-callbacks.js +parallel/test-http-write-empty-string.js +parallel/test-http-write-head-2.js +parallel/test-http-write-head-after-set-header.js +parallel/test-http-write-head.js +parallel/test-http-zerolengthbuffer.js +parallel/test-http-zero-length-write.js +parallel/test-icu-data-dir.js +parallel/test-icu-env.js +parallel/test-icu-minimum-version.js +parallel/test-icu-stringwidth.js +parallel/test-icu-transcode.js +parallel/test-inspect-address-in-use.js +parallel/test-inspect-async-hook-setup-at-inspect.js +parallel/test-inspector-already-activated-cli.js +parallel/test-inspector-async-call-stack-abort.js +parallel/test-inspector-async-call-stack.js +parallel/test-inspector-async-context-brk.js +parallel/test-inspector-async-hook-after-done.js +parallel/test-inspector-async-hook-setup-at-inspect-brk.js +parallel/test-inspector-async-hook-setup-at-signal.js +parallel/test-inspector-async-stack-traces-promise-then.js +parallel/test-inspector-async-stack-traces-set-interval.js +parallel/test-inspector-bindings.js +parallel/test-inspector-break-e.js +parallel/test-inspector-break-when-eval.js +parallel/test-inspector-close-worker.js +parallel/test-inspector-connect-main-thread.js +parallel/test-inspector-connect-to-main-thread.js +parallel/test-inspector-console.js +parallel/test-inspector-console-top-frame.js +parallel/test-inspector-contexts.js +parallel/test-inspector-debug-brk-flag.js +parallel/test-inspector-debug-end.js +parallel/test-inspector-emit-protocol-event.js +parallel/test-inspector-enabled.js +parallel/test-inspector-esm.js +parallel/test-inspector-exception.js +parallel/test-inspector-exit-worker-in-wait-for-connection2.js +parallel/test-inspector-exit-worker-in-wait-for-connection.js +parallel/test-inspector-has-idle.js +parallel/test-inspector-has-inspector-false.js +parallel/test-inspector-heap-allocation-tracker.js +parallel/test-inspector-heapdump.js +parallel/test-inspector-inspect-brk-node.js +parallel/test-inspector-invalid-args.js +parallel/test-inspector-ip-detection.js +parallel/test-inspector.js +parallel/test-inspector-module.js +parallel/test-inspector-multisession-js.js +parallel/test-inspector-multisession-ws.js +parallel/test-inspector-network-fetch.js +parallel/test-inspector-network-http.js +parallel/test-inspector-not-blocked-on-idle.js +parallel/test-inspector-open-coverage.js +parallel/test-inspector-open.js +parallel/test-inspector-open-port-integer-overflow.js +parallel/test-inspector-port-zero-cluster.js +parallel/test-inspector-port-zero.js +parallel/test-inspector-promises.js +parallel/test-inspector-reported-host.js +parallel/test-inspector-resource-name-to-url.js +parallel/test-inspector-runtime-evaluate-with-timeout.js +parallel/test-inspector-scriptparsed-context.js +parallel/test-inspector-stop-profile-after-done.js +parallel/test-inspector-stops-no-file.js +parallel/test-inspector-stress-http.js +parallel/test-inspector-strip-types.js +parallel/test-inspector-tracing-domain.js +parallel/test-inspector-vm-global-accessors-getter-sideeffect.js +parallel/test-inspector-vm-global-accessors-sideeffects.js +parallel/test-inspector-wait-for-connection.js +parallel/test-inspector-waiting-for-disconnect.js +parallel/test-inspector-workers-flat-list.js +parallel/test-inspect-publish-uid.js +parallel/test-inspect-support-for-node_options.js +parallel/test-instanceof.js +parallel/test-internal-assert.js +parallel/test-internal-error-original-names.js +parallel/test-internal-errors.js +parallel/test-internal-fs.js +parallel/test-internal-fs-syncwritestream.js +parallel/test-internal-module-require.js +parallel/test-internal-modules.js +parallel/test-internal-module-wrap.js +parallel/test-internal-only-binding.js +parallel/test-internal-process-binding.js +parallel/test-internal-socket-list-receive.js +parallel/test-internal-socket-list-send.js +parallel/test-internal-util-assertCrypto.js +parallel/test-internal-util-classwrapper.js +parallel/test-internal-util-decorate-error-stack.js +parallel/test-internal-util-helpers.js +parallel/test-internal-util-normalizeencoding.js +parallel/test-internal-util-objects.js +parallel/test-internal-util-weakreference.js +parallel/test-internal-validators-validateoneof.js +parallel/test-internal-validators-validateport.js +parallel/test-internal-webidl-converttoint.js +parallel/test-intl.js +parallel/test-intl-v8BreakIterator.js +parallel/test-js-stream-call-properties.js +parallel/test-kill-segfault-freebsd.js +parallel/test-listen-fd-cluster.js +parallel/test-listen-fd-detached-inherit.js +parallel/test-listen-fd-detached.js +parallel/test-listen-fd-server.js +parallel/test-macos-app-sandbox.js +parallel/test-math-random.js +parallel/test-memory-usage-emfile.js +parallel/test-memory-usage.js +parallel/test-messagechannel.js +parallel/test-messageevent-brandcheck.js +parallel/test-messageport-hasref.js +parallel/test-messaging-marktransfermode.js +parallel/test-microtask-queue-integration.js +parallel/test-microtask-queue-run-immediate.js +parallel/test-microtask-queue-run.js +parallel/test-mime-api.js +parallel/test-mime-whatwg.js +parallel/test-module-builtin.js +parallel/test-module-cache.js +parallel/test-module-children.js +parallel/test-module-circular-dependency-warning.js +parallel/test-module-circular-symlinks.js +parallel/test-module-create-require.js +parallel/test-module-create-require-multibyte.js +parallel/test-module-globalpaths-nodepath.js +parallel/test-module-isBuiltin.js +parallel/test-module-loading-deprecated.js +parallel/test-module-loading-error.js +parallel/test-module-loading-globalpaths.js +parallel/test-module-main-extension-lookup.js +parallel/test-module-main-fail.js +parallel/test-module-main-preserve-symlinks-fail.js +parallel/test-module-multi-extensions.js +parallel/test-module-nodemodulepaths.js +parallel/test-module-parent-deprecation.js +parallel/test-module-parent-setter-deprecation.js +parallel/test-module-prototype-mutation.js +parallel/test-module-readonly.js +parallel/test-module-relative-lookup.js +parallel/test-module-run-main-monkey-patch.js +parallel/test-module-setsourcemapssupport.js +parallel/test-module-stat.js +parallel/test-module-strip-types.js +parallel/test-module-symlinked-peer-modules.js +parallel/test-module-version.js +parallel/test-module-wrap.js +parallel/test-module-wrapper.js +parallel/test-navigator.js +parallel/test-net-access-byteswritten.js +parallel/test-net-after-close.js +parallel/test-net-allow-half-open.js +parallel/test-net-autoselectfamily-attempt-timeout-cli-option.js +parallel/test-net-autoselectfamily-attempt-timeout-default-value.js +parallel/test-net-autoselectfamily-commandline-option.js +parallel/test-net-autoselectfamily-default.js +parallel/test-net-autoselectfamily-ipv4first.js +parallel/test-net-autoselectfamily.js +parallel/test-net-better-error-messages-listen.js +parallel/test-net-better-error-messages-listen-path.js +parallel/test-net-better-error-messages-path.js +parallel/test-net-better-error-messages-port-hostname.js +parallel/test-net-binary.js +parallel/test-net-bind-twice.js +parallel/test-net-blocklist.js +parallel/test-net-buffersize.js +parallel/test-net-bytes-read.js +parallel/test-net-bytes-stats.js +parallel/test-net-bytes-written-large.js +parallel/test-net-can-reset-timeout.js +parallel/test-net-child-process-connect-reset.js +parallel/test-net-client-bind-twice.js +parallel/test-net-connect-abort-controller.js +parallel/test-net-connect-after-destroy.js +parallel/test-net-connect-buffer2.js +parallel/test-net-connect-buffer.js +parallel/test-net-connect-call-socket-connect.js +parallel/test-net-connect-destroy.js +parallel/test-net-connect-immediate-destroy.js +parallel/test-net-connect-immediate-finish.js +parallel/test-net-connect-keepalive.js +parallel/test-net-connect-memleak.js +parallel/test-net-connect-no-arg.js +parallel/test-net-connect-nodelay.js +parallel/test-net-connect-options-allowhalfopen.js +parallel/test-net-connect-options-fd.js +parallel/test-net-connect-options-invalid.js +parallel/test-net-connect-options-ipv6.js +parallel/test-net-connect-options-path.js +parallel/test-net-connect-options-port.js +parallel/test-net-connect-paused-connection.js +parallel/test-net-connect-reset-after-destroy.js +parallel/test-net-connect-reset-before-connected.js +parallel/test-net-connect-reset.js +parallel/test-net-connect-reset-until-connected.js +parallel/test-net-deprecated-setsimultaneousaccepts.js +parallel/test-net-dns-custom-lookup.js +parallel/test-net-dns-error.js +parallel/test-net-dns-lookup.js +parallel/test-net-dns-lookup-skip.js +parallel/test-net-during-close.js +parallel/test-net-eaddrinuse.js +parallel/test-net-end-close.js +parallel/test-net-end-destroyed.js +parallel/test-net-end-without-connect.js +parallel/test-net-error-twice.js +parallel/test-net-isip.js +parallel/test-net-isipv4.js +parallel/test-net-isipv6.js +parallel/test-net-keepalive.js +parallel/test-net-large-string.js +parallel/test-net-listen-after-destroying-stdin.js +parallel/test-net-listen-close-server-callback-is-not-function.js +parallel/test-net-listen-close-server.js +parallel/test-net-listen-error.js +parallel/test-net-listen-exclusive-random-ports.js +parallel/test-net-listen-fd0.js +parallel/test-net-listen-handle-in-cluster-1.js +parallel/test-net-listen-handle-in-cluster-2.js +parallel/test-net-listening.js +parallel/test-net-listen-invalid-port.js +parallel/test-net-listen-ipv6only.js +parallel/test-net-listen-twice.js +parallel/test-net-local-address-port.js +parallel/test-net-localerror.js +parallel/test-net-normalize-args.js +parallel/test-net-onread-static-buffer.js +parallel/test-net-options-lookup.js +parallel/test-net-pause-resume-connecting.js +parallel/test-net-perf_hooks.js +parallel/test-net-persistent-keepalive.js +parallel/test-net-persistent-nodelay.js +parallel/test-net-persistent-ref-unref.js +parallel/test-net-pingpong.js +parallel/test-net-pipe-connect-errors.js +parallel/test-net-reconnect.js +parallel/test-net-remote-address.js +parallel/test-net-remote-address-port.js +parallel/test-net-reuseport.js +parallel/test-net-server-blocklist.js +parallel/test-net-server-call-listen-multiple-times.js +parallel/test-net-server-capture-rejection.js +parallel/test-net-server-close-before-calling-lookup-callback.js +parallel/test-net-server-close-before-ipc-response.js +parallel/test-net-server-close.js +parallel/test-net-server-drop-connections-in-cluster.js +parallel/test-net-server-drop-connections.js +parallel/test-net-server-keepalive.js +parallel/test-net-server-listen-handle.js +parallel/test-net-server-listen-options.js +parallel/test-net-server-listen-options-signal.js +parallel/test-net-server-listen-path.js +parallel/test-net-server-listen-remove-callback.js +parallel/test-net-server-max-connections-close-makes-more-available.js +parallel/test-net-server-max-connections.js +parallel/test-net-server-nodelay.js +parallel/test-net-server-options.js +parallel/test-net-server-pause-on-connect.js +parallel/test-net-server-reset.js +parallel/test-net-server-simultaneous-accepts-produce-warning-once.js +parallel/test-net-server-try-ports.js +parallel/test-net-server-unref.js +parallel/test-net-server-unref-persistent.js +parallel/test-net-settimeout.js +parallel/test-net-socket-byteswritten.js +parallel/test-net-socket-close-after-end.js +parallel/test-net-socket-connecting.js +parallel/test-net-socket-connect-invalid-autoselectfamilyattempttimeout.js +parallel/test-net-socket-connect-invalid-autoselectfamily.js +parallel/test-net-socket-constructor.js +parallel/test-net-socket-destroy-send.js +parallel/test-net-socket-destroy-twice.js +parallel/test-net-socket-end-before-connect.js +parallel/test-net-socket-end-callback.js +parallel/test-net-socket-local-address.js +parallel/test-net-socket-no-halfopen-enforcer.js +parallel/test-net-socket-ready-without-cb.js +parallel/test-net-socket-reset-send.js +parallel/test-net-socket-reset-twice.js +parallel/test-net-socket-setnodelay.js +parallel/test-net-socket-timeout.js +parallel/test-net-socket-timeout-unref.js +parallel/test-net-socket-write-after-close.js +parallel/test-net-socket-write-error.js +parallel/test-net-stream.js +parallel/test-net-sync-cork.js +parallel/test-net-throttle.js +parallel/test-net-timeout-no-handle.js +parallel/test-net-writable.js +parallel/test-net-write-after-close.js +parallel/test-net-write-after-end-nt.js +parallel/test-net-write-arguments.js +parallel/test-net-write-cb-on-destroy-before-connect.js +parallel/test-net-write-connect-write.js +parallel/test-net-write-fully-async-buffer.js +parallel/test-net-write-fully-async-hex-string.js +parallel/test-net-write-slow.js +parallel/test-next-tick-doesnt-hang.js +parallel/test-next-tick-domain.js +parallel/test-next-tick-errors.js +parallel/test-next-tick-fixed-queue-regression.js +parallel/test-next-tick-intentional-starvation.js +parallel/test-next-tick.js +parallel/test-next-tick-ordering2.js +parallel/test-next-tick-ordering.js +parallel/test-next-tick-when-exiting.js +parallel/test-no-addons-resolution-condition.js +parallel/test-nodeeventtarget.js +parallel/test-node-run.js +parallel/test-no-node-snapshot.js +parallel/test-npm-install.js +parallel/test-npm-version.js +parallel/test-openssl-ca-options.js +parallel/test-options-binding.js +parallel/test-os-checked-function.js +parallel/test-os-eol.js +parallel/test-os-homedir-no-envvar.js +parallel/test-os.js +parallel/test-os-process-priority.js +parallel/test-os-userinfo-handles-getter-errors.js +parallel/test-outgoing-message-destroy.js +parallel/test-outgoing-message-pipe.js +parallel/test-path-basename.js +parallel/test-path-dirname.js +parallel/test-path-extname.js +parallel/test-path-glob.js +parallel/test-path-isabsolute.js +parallel/test-path-join.js +parallel/test-path.js +parallel/test-path-makelong.js +parallel/test-path-normalize.js +parallel/test-path-parse-format.js +parallel/test-path-posix-exists.js +parallel/test-path-posix-relative-on-windows.js +parallel/test-path-relative.js +parallel/test-path-resolve.js +parallel/test-path-win32-exists.js +parallel/test-path-zero-length-strings.js +parallel/test-pending-deprecation.js +parallel/test-perf-gc-crash.js +parallel/test-perf-hooks-histogram.js +parallel/test-perf-hooks-resourcetiming.js +parallel/test-perf-hooks-usertiming.js +parallel/test-perf-hooks-worker-timeorigin.js +parallel/test-performance-eventlooputil.js +parallel/test-performance-function-async.js +parallel/test-performance-function.js +parallel/test-performance-gc.js +parallel/test-performance-global.js +parallel/test-performance-measure-detail.js +parallel/test-performance-measure.js +parallel/test-performance-nodetiming.js +parallel/test-performance-nodetiming-uvmetricsinfo.js +parallel/test-performanceobserver-gc.js +parallel/test-performanceobserver.js +parallel/test-performance-resourcetimingbufferfull.js +parallel/test-performance-resourcetimingbuffersize.js +parallel/test-permission-allow-addons-cli.js +parallel/test-permission-allow-child-process-cli.js +parallel/test-permission-allow-wasi-cli.js +parallel/test-permission-allow-worker-cli.js +parallel/test-permission-child-process-cli.js +parallel/test-permission-dc-worker-threads.js +parallel/test-permission-fs-absolute-path.js +parallel/test-permission-fs-read.js +parallel/test-permission-fs-relative-path.js +parallel/test-permission-fs-repeat-path.js +parallel/test-permission-fs-require.js +parallel/test-permission-fs-supported.js +parallel/test-permission-fs-symlink.js +parallel/test-permission-fs-symlink-relative.js +parallel/test-permission-fs-symlink-target-write.js +parallel/test-permission-fs-traversal-path.js +parallel/test-permission-fs-wildcard.js +parallel/test-permission-fs-windows-path.js +parallel/test-permission-fs-write-report.js +parallel/test-permission-fs-write-v8.js +parallel/test-permission-has.js +parallel/test-permission-inspector-brk.js +parallel/test-permission-inspector.js +parallel/test-permission-no-addons.js +parallel/test-permission-processbinding.js +parallel/test-permission-sqlite-load-extension.js +parallel/test-permission-warning-flags.js +parallel/test-permission-wasi.js +parallel/test-permission-worker-threads-cli.js +parallel/test-pipe-abstract-socket-http.js +parallel/test-pipe-abstract-socket.js +parallel/test-pipe-address.js +parallel/test-pipe-file-to-http.js +parallel/test-pipe-head.js +parallel/test-pipe-outgoing-message-data-emitted-after-ended.js +parallel/test-pipe-return-val.js +parallel/test-pipe-stream.js +parallel/test-pipe-unref.js +parallel/test-pipe-writev.js +parallel/test-preload.js +parallel/test-preload-print-process-argv.js +parallel/test-preload-self-referential.js +parallel/test-preload-worker.js +parallel/test-primitive-timer-leak.js +parallel/test-primordials-apply.js +parallel/test-primordials-promise.js +parallel/test-primordials-regexp.js +parallel/test-priority-queue.js +parallel/test-process-abort.js +parallel/test-process-argv-0.js +parallel/test-process-assert.js +parallel/test-process-available-memory.js +parallel/test-process-beforeexit.js +parallel/test-process-beforeexit-throw-exit.js +parallel/test-process-binding-internalbinding-allowlist.js +parallel/test-process-binding.js +parallel/test-process-binding-util.js +parallel/test-process-chdir-errormessage.js +parallel/test-process-chdir.js +parallel/test-process-config.js +parallel/test-process-constants-noatime.js +parallel/test-process-constrained-memory.js +parallel/test-process-cpuUsage.js +parallel/test-process-default.js +parallel/test-process-dlopen-undefined-exports.js +parallel/test-process-domain-segfault.js +parallel/test-process-emit.js +parallel/test-process-emitwarning.js +parallel/test-process-env-allowed-flags-are-documented.js +parallel/test-process-env-allowed-flags.js +parallel/test-process-env-delete.js +parallel/test-process-env-deprecation.js +parallel/test-process-env-ignore-getter-setter.js +parallel/test-process-env.js +parallel/test-process-env-sideeffects.js +parallel/test-process-env-symbols.js +parallel/test-process-env-tz.js +parallel/test-process-env-windows-error-reset.js +parallel/test-process-euid-egid.js +parallel/test-process-exception-capture-errors.js +parallel/test-process-exception-capture.js +parallel/test-process-exception-capture-should-abort-on-uncaught.js +parallel/test-process-exception-capture-should-abort-on-uncaught-setflagsfromstring.js +parallel/test-process-exec-argv.js +parallel/test-process-execpath.js +parallel/test-process-exit-code.js +parallel/test-process-exit-code-validation.js +parallel/test-process-exit-from-before-exit.js +parallel/test-process-exit-handler.js +parallel/test-process-exit.js +parallel/test-process-exit-recursive.js +parallel/test-process-external-stdio-close.js +parallel/test-process-external-stdio-close-spawn.js +parallel/test-process-features.js +parallel/test-process-getactivehandles.js +parallel/test-process-getactiverequests.js +parallel/test-process-getactiveresources-track-active-handles.js +parallel/test-process-getactiveresources-track-interval-lifetime.js +parallel/test-process-getactiveresources-track-multiple-timers.js +parallel/test-process-getactiveresources-track-timer-lifetime.js +parallel/test-process-getgroups.js +parallel/test-process-hrtime-bigint.js +parallel/test-process-hrtime.js +parallel/test-process-initgroups.js +parallel/test-process-kill-null.js +parallel/test-process-kill-pid.js +parallel/test-process-next-tick.js +parallel/test-process-no-deprecation.js +parallel/test-process-ppid.js +parallel/test-process-prototype.js +parallel/test-process-raw-debug.js +parallel/test-process-really-exit.js +parallel/test-process-redirect-warnings-env.js +parallel/test-process-redirect-warnings.js +parallel/test-process-ref-unref.js +parallel/test-process-release.js +parallel/test-process-remove-all-signal-listeners.js +parallel/test-process-setgroups.js +parallel/test-process-setsourcemapsenabled.js +parallel/test-process-title-cli.js +parallel/test-process-uid-gid.js +parallel/test-process-umask.js +parallel/test-process-umask-mask.js +parallel/test-process-uncaught-exception-monitor.js +parallel/test-process-uptime.js +parallel/test-process-warning.js +parallel/test-promise-handled-rejection-no-warning.js +parallel/test-promise-hook-create-hook.js +parallel/test-promise-hook-exceptions.js +parallel/test-promise-hook-on-after.js +parallel/test-promise-hook-on-before.js +parallel/test-promise-hook-on-init.js +parallel/test-promise-hook-on-resolve.js +parallel/test-promise-reject-callback-exception.js +parallel/test-promises-unhandled-proxy-rejections.js +parallel/test-promises-unhandled-rejections.js +parallel/test-promises-unhandled-symbol-rejections.js +parallel/test-promise-swallowed-event.js +parallel/test-promises-warning-on-unhandled-rejection.js +parallel/test-promise-unhandled-default.js +parallel/test-promise-unhandled-error.js +parallel/test-promise-unhandled-flag.js +parallel/test-promise-unhandled-issue-43655.js +parallel/test-promise-unhandled-silent.js +parallel/test-promise-unhandled-silent-no-hook.js +parallel/test-promise-unhandled-throw-handler.js +parallel/test-promise-unhandled-throw.js +parallel/test-promise-unhandled-warn.js +parallel/test-promise-unhandled-warn-no-hook.js +parallel/test-punycode.js +parallel/test-querystring-escape.js +parallel/test-querystring.js +parallel/test-querystring-maxKeys-non-finite.js +parallel/test-querystring-multichar-separator.js +parallel/test-queue-microtask.js +parallel/test-queue-microtask-uncaught-asynchooks.js +parallel/test-quic-internal-endpoint-listen-defaults.js +parallel/test-quic-internal-endpoint-options.js +parallel/test-quic-internal-endpoint-stats-state.js +parallel/test-quic-internal-setcallbacks.js +parallel/test-readable-from-iterator-closing.js +parallel/test-readable-from.js +parallel/test-readable-from-web-enqueue-then-close.js +parallel/test-readable-large-hwm.js +parallel/test-readable-single-end.js +parallel/test-readline-async-iterators-backpressure.js +parallel/test-readline-async-iterators-destroy.js +parallel/test-readline-async-iterators.js +parallel/test-readline-carriage-return-between-chunks.js +parallel/test-readline-csi.js +parallel/test-readline-emit-keypress-events.js +parallel/test-readline-input-onerror.js +parallel/test-readline-interface-escapecodetimeout.js +parallel/test-readline-interface.js +parallel/test-readline-interface-no-trailing-newline.js +parallel/test-readline-interface-recursive-writes.js +parallel/test-readline.js +parallel/test-readline-keys.js +parallel/test-readline-position.js +parallel/test-readline-promises-interface.js +parallel/test-readline-promises-tab-complete.js +parallel/test-readline-reopen.js +parallel/test-readline-set-raw-mode.js +parallel/test-readline-tab-complete.js +parallel/test-readline-undefined-columns.js +parallel/test-ref-unref-return.js +parallel/test-regression-object-prototype.js +parallel/test-release-changelog.js +parallel/test-release-npm.js +parallel/test-repl-array-prototype-tempering.js +parallel/test-repl-autocomplete.js +parallel/test-repl-autolibs.js +parallel/test-repl-clear-immediate-crash.js +parallel/test-repl-cli-eval.js +parallel/test-repl-colors.js +parallel/test-repl-context.js +parallel/test-repl-definecommand.js +parallel/test-repl-domain.js +parallel/test-repl-dynamic-import.js +parallel/test-repl-editor.js +parallel/test-repl-empty.js +parallel/test-repl-end-emits-exit.js +parallel/test-repl-envvars.js +parallel/test-repl-eval.js +parallel/test-repl-function-definition-edge-case.js +parallel/test-repl-harmony.js +parallel/test-repl-history-navigation.js +parallel/test-repl-history-perm.js +parallel/test-repl-import-referrer.js +parallel/test-repl-inspect-defaults.js +parallel/test-repl-inspector.js +parallel/test-repl.js +parallel/test-repl-let-process.js +parallel/test-repl-load-multiline.js +parallel/test-repl-load-multiline-no-trailing-newline.js +parallel/test-repl-mode.js +parallel/test-repl-multiline.js +parallel/test-repl-no-terminal.js +parallel/test-repl-null.js +parallel/test-repl-null-thrown.js +parallel/test-repl-options.js +parallel/test-repl-permission-model.js +parallel/test-repl-persistent-history.js +parallel/test-repl-preprocess-top-level-await.js +parallel/test-repl-pretty-custom-stack.js +parallel/test-repl-pretty-stack-custom-writer.js +parallel/test-repl-pretty-stack.js +parallel/test-repl-preview.js +parallel/test-repl-preview-newlines.js +parallel/test-repl-preview-without-inspector.js +parallel/test-repl-programmatic-history.js +parallel/test-repl-recoverable.js +parallel/test-repl-require-after-write.js +parallel/test-repl-require-cache.js +parallel/test-repl-require-context.js +parallel/test-repl-require.js +parallel/test-repl-require-self-referential.js +parallel/test-repl-reset-event.js +parallel/test-repl-reverse-search.js +parallel/test-repl-save-load.js +parallel/test-repl-setprompt.js +parallel/test-repl-sigint.js +parallel/test-repl-sigint-nested-eval.js +parallel/test-repl-stdin-push-null.js +parallel/test-repl-strict-mode-previews.js +parallel/test-repl-syntax-error-handling.js +parallel/test-repl-syntax-error-stack.js +parallel/test-repl-tab-complete-crash.js +parallel/test-repl-tab-complete-import.js +parallel/test-repl-tab-complete.js +parallel/test-repl-tab-complete-nested-repls.js +parallel/test-repl-tab-complete-no-warn.js +parallel/test-repl-tab-complete-on-editor-mode.js +parallel/test-repl-tab.js +parallel/test-repl-throw-null-or-undefined.js +parallel/test-repl-top-level-await.js +parallel/test-repl-uncaught-exception-async.js +parallel/test-repl-uncaught-exception-evalcallback.js +parallel/test-repl-uncaught-exception.js +parallel/test-repl-uncaught-exception-standalone.js +parallel/test-repl-underscore.js +parallel/test-repl-unexpected-token-recoverable.js +parallel/test-repl-unsafe-array-iteration.js +parallel/test-repl-unsupported-option.js +parallel/test-repl-use-global.js +parallel/test-require-cache.js +parallel/test-require-delete-array-iterator.js +parallel/test-require-dot.js +parallel/test-require-empty-main.js +parallel/test-require-enoent-dir.js +parallel/test-require-exceptions.js +parallel/test-require-extension-over-directory.js +parallel/test-require-extensions-main.js +parallel/test-require-extensions-same-filename-as-dir.js +parallel/test-require-extensions-same-filename-as-dir-trailing-slash.js +parallel/test-require-invalid-main-no-exports.js +parallel/test-require-invalid-package.js +parallel/test-require-json.js +parallel/test-require-long-path.js +parallel/test-require-mjs.js +parallel/test-require-node-prefix.js +parallel/test-require-nul.js +parallel/test-require-process.js +parallel/test-require-resolve.js +parallel/test-require-resolve-opts-paths-relative.js +parallel/test-require-symlink.js +parallel/test-require-unicode.js +parallel/test-resource-usage.js +parallel/test-runner-aliases.js +parallel/test-runner-assert.js +parallel/test-runner-cli-concurrency.js +parallel/test-runner-cli-timeout.js +parallel/test-runner-concurrency.js +parallel/test-runner-custom-assertions.js +parallel/test-runner-enable-source-maps-issue.js +parallel/test-runner-exit-code.js +parallel/test-runner-extraneous-async-activity.js +parallel/test-runner-filetest-location.js +parallel/test-runner-filter-warning.js +parallel/test-runner-force-exit-failure.js +parallel/test-runner-force-exit-flush.js +parallel/test-runner-import-no-scheme.js +parallel/test-runner-misc.js +parallel/test-runner-mocking.js +parallel/test-runner-mock-timers-date.js +parallel/test-runner-mock-timers.js +parallel/test-runner-mock-timers-scheduler.js +parallel/test-runner-module-mocking.js +parallel/test-runner-no-isolation-filtering.js +parallel/test-runner-option-validation.js +parallel/test-runner-reporters.js +parallel/test-runner-root-after-with-refed-handles.js +parallel/test-runner-root-duration.js +parallel/test-runner-snapshot-file-tests.js +parallel/test-runner-snapshot-tests.js +parallel/test-runner-source-maps-invalid-json.js +parallel/test-runner-string-to-regexp.js +parallel/test-runner-subtest-after-hook.js +parallel/test-runner-test-filepath.js +parallel/test-runner-test-fullname.js +parallel/test-runner-todo-skip-tests.js +parallel/test-runner-typechecking.js +parallel/test-runner-wait-for.js +parallel/test-safe-get-env.js +parallel/test-security-revert-unknown.js +parallel/test-set-http-max-http-headers.js +parallel/test-set-incoming-message-header.js +parallel/test-set-process-debug-port.js +parallel/test-setproctitle.js +parallel/test-shadow-realm-allowed-builtin-modules.js +parallel/test-shadow-realm-custom-loaders.js +parallel/test-shadow-realm-gc.js +parallel/test-shadow-realm-gc-module.js +parallel/test-shadow-realm-globals.js +parallel/test-shadow-realm-import-value-resolve.js +parallel/test-shadow-realm.js +parallel/test-shadow-realm-module.js +parallel/test-shadow-realm-preload-module.js +parallel/test-shadow-realm-prepare-stack-trace.js +parallel/test-sigint-infinite-loop.js +parallel/test-signal-args.js +parallel/test-signal-handler.js +parallel/test-signal-handler-remove-on-exit.js +parallel/test-signal-safety.js +parallel/test-signal-unregister.js +parallel/test-single-executable-blob-config-errors.js +parallel/test-single-executable-blob-config.js +parallel/test-snapshot-api.js +parallel/test-snapshot-argv1.js +parallel/test-snapshot-basic.js +parallel/test-snapshot-child-process-sync.js +parallel/test-snapshot-cjs-main.js +parallel/test-snapshot-config.js +parallel/test-snapshot-console.js +parallel/test-snapshot-coverage.js +parallel/test-snapshot-cwd.js +parallel/test-snapshot-dns-lookup-localhost.js +parallel/test-snapshot-dns-lookup-localhost-promise.js +parallel/test-snapshot-dns-resolve-localhost.js +parallel/test-snapshot-dns-resolve-localhost-promise.js +parallel/test-snapshot-error.js +parallel/test-snapshot-eval.js +parallel/test-snapshot-gzip.js +parallel/test-snapshot-namespaced-builtin.js +parallel/test-snapshot-net.js +parallel/test-snapshot-reproducible.js +parallel/test-snapshot-stack-trace-limit.js +parallel/test-snapshot-stack-trace-limit-mutation.js +parallel/test-snapshot-typescript.js +parallel/test-snapshot-umd.js +parallel/test-snapshot-weak-reference.js +parallel/test-snapshot-worker.js +parallel/test-socket-address.js +parallel/test-socketaddress.js +parallel/test-socket-options-invalid.js +parallel/test-socket-write-after-fin-error.js +parallel/test-socket-write-after-fin.js +parallel/test-socket-writes-before-passed-to-tls-socket.js +parallel/test-source-map-api.js +parallel/test-source-map-cjs-require-cache.js +parallel/test-source-map-enable.js +parallel/test-spawn-cmd-named-pipe.js +parallel/test-sqlite-custom-functions.js +parallel/test-sqlite-database-sync.js +parallel/test-sqlite-data-types.js +parallel/test-sqlite.js +parallel/test-sqlite-named-parameters.js +parallel/test-sqlite-session.js +parallel/test-sqlite-statement-sync.js +parallel/test-sqlite-transactions.js +parallel/test-sqlite-typed-array-and-data-view.js +parallel/test-stack-size-limit.js +parallel/test-startup-empty-regexp-statics.js +parallel/test-startup-large-pages.js +parallel/test-stdin-child-proc.js +parallel/test-stdin-from-file.js +parallel/test-stdin-from-file-spawn.js +parallel/test-stdin-hang.js +parallel/test-stdin-pause-resume.js +parallel/test-stdin-pause-resume-sync.js +parallel/test-stdin-pipe-large.js +parallel/test-stdin-pipe-resume.js +parallel/test-stdin-resume-pause.js +parallel/test-stdin-script-child.js +parallel/test-stdin-script-child-option.js +parallel/test-stdio-closed.js +parallel/test-stdio-pipe-access.js +parallel/test-stdio-pipe-redirect.js +parallel/test-stdio-pipe-stderr.js +parallel/test-stdio-undestroy.js +parallel/test-stdout-cannot-be-closed-child-process-pipe.js +parallel/test-stdout-close-catch.js +parallel/test-stdout-close-unref.js +parallel/test-stdout-pipeline-destroy.js +parallel/test-stdout-stderr-reading.js +parallel/test-stdout-stderr-write.js +parallel/test-stdout-to-file.js +parallel/test-strace-openat-openssl.js +parallel/test-stream2-base64-single-char-read-end.js +parallel/test-stream2-basic.js +parallel/test-stream2-compatibility.js +parallel/test-stream2-decode-partial.js +parallel/test-stream2-finish-pipe-error.js +parallel/test-stream2-finish-pipe.js +parallel/test-stream2-httpclient-response-end.js +parallel/test-stream2-large-read-stall.js +parallel/test-stream2-objects.js +parallel/test-stream2-pipe-error-handling.js +parallel/test-stream2-pipe-error-once-listener.js +parallel/test-stream2-push.js +parallel/test-stream2-readable-empty-buffer-no-eof.js +parallel/test-stream2-readable-legacy-drain.js +parallel/test-stream2-readable-non-empty-end.js +parallel/test-stream2-readable-wrap-destroy.js +parallel/test-stream2-readable-wrap-empty.js +parallel/test-stream2-readable-wrap-error.js +parallel/test-stream2-readable-wrap.js +parallel/test-stream2-read-sync-stack.js +parallel/test-stream2-set-encoding.js +parallel/test-stream2-transform.js +parallel/test-stream2-unpipe-drain.js +parallel/test-stream2-unpipe-leak.js +parallel/test-stream2-writable.js +parallel/test-stream3-cork-end.js +parallel/test-stream3-cork-uncork.js +parallel/test-stream3-pause-then-read.js +parallel/test-stream3-pipeline-async-iterator.js +parallel/test-stream-add-abort-signal.js +parallel/test-stream-aliases-legacy.js +parallel/test-stream-auto-destroy.js +parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js +parallel/test-stream-backpressure.js +parallel/test-stream-base-prototype-accessors-enumerability.js +parallel/test-stream-base-typechecking.js +parallel/test-stream-big-packet.js +parallel/test-stream-big-push.js +parallel/test-stream-catch-rejections.js +parallel/test-stream-compose.js +parallel/test-stream-compose-operator.js +parallel/test-stream-construct.js +parallel/test-stream-consumers.js +parallel/test-stream-decoder-objectmode.js +parallel/test-stream-destroy-event-order.js +parallel/test-stream-destroy.js +parallel/test-stream-drop-take.js +parallel/test-stream-duplex-destroy.js +parallel/test-stream-duplex-end.js +parallel/test-stream-duplex-from.js +parallel/test-stream-duplex.js +parallel/test-stream-duplexpair.js +parallel/test-stream-duplex-props.js +parallel/test-stream-duplex-readable-end.js +parallel/test-stream-duplex-readable-writable.js +parallel/test-stream-duplex-writable-finished.js +parallel/test-stream-end-of-streams.js +parallel/test-stream-end-paused.js +parallel/test-stream-err-multiple-callback-construction.js +parallel/test-stream-error-once.js +parallel/test-stream-event-names.js +parallel/test-stream-events-prepend.js +parallel/test-stream-filter.js +parallel/test-stream-finished.js +parallel/test-stream-flatMap.js +parallel/test-stream-forEach.js +parallel/test-stream-inheritance.js +parallel/test-stream-ispaused.js +parallel/test-stream-map.js +parallel/test-stream-objectmode-undefined.js +parallel/test-stream-once-readable-pipe.js +parallel/test-stream-passthrough-drain.js +parallel/test-stream-pipe-after-end.js +parallel/test-stream-pipe-await-drain.js +parallel/test-stream-pipe-await-drain-manual-resume.js +parallel/test-stream-pipe-await-drain-push-while-write.js +parallel/test-stream-pipe-cleanup.js +parallel/test-stream-pipe-cleanup-pause.js +parallel/test-stream-pipe-deadlock.js +parallel/test-stream-pipe-error-handling.js +parallel/test-stream-pipe-error-unhandled.js +parallel/test-stream-pipe-event.js +parallel/test-stream-pipe-flow-after-unpipe.js +parallel/test-stream-pipe-flow.js +parallel/test-stream-pipeline-async-iterator.js +parallel/test-stream-pipeline-duplex.js +parallel/test-stream-pipeline-http2.js +parallel/test-stream-pipeline.js +parallel/test-stream-pipeline-listeners.js +parallel/test-stream-pipeline-process.js +parallel/test-stream-pipeline-queued-end-in-destroy.js +parallel/test-stream-pipeline-uncaught.js +parallel/test-stream-pipeline-with-empty-string.js +parallel/test-stream-pipe-manual-resume.js +parallel/test-stream-pipe-multiple-pipes.js +parallel/test-stream-pipe-needDrain.js +parallel/test-stream-pipe-same-destination-twice.js +parallel/test-stream-pipe-unpipe-streams.js +parallel/test-stream-pipe-without-listenerCount.js +parallel/test-stream-preprocess.js +parallel/test-stream-promises.js +parallel/test-stream-push-order.js +parallel/test-stream-push-strings.js +parallel/test-stream-readable-aborted.js +parallel/test-stream-readable-add-chunk-during-data.js +parallel/test-stream-readable-async-iterators.js +parallel/test-stream-readable-constructor-set-methods.js +parallel/test-stream-readable-data.js +parallel/test-stream-readable-default-encoding.js +parallel/test-stream-readable-destroy.js +parallel/test-stream-readable-didRead.js +parallel/test-stream-readable-dispose.js +parallel/test-stream-readable-emit-readable-short-stream.js +parallel/test-stream-readable-emittedReadable.js +parallel/test-stream-readable-end-destroyed.js +parallel/test-stream-readable-ended.js +parallel/test-stream-readable-error-end.js +parallel/test-stream-readable-event.js +parallel/test-stream-readable-flow-recursion.js +parallel/test-stream-readable-from-web-termination.js +parallel/test-stream-readable-hwm-0-async.js +parallel/test-stream-readable-hwm-0.js +parallel/test-stream-readable-hwm-0-no-flow-data.js +parallel/test-stream-readable-infinite-read.js +parallel/test-stream-readable-invalid-chunk.js +parallel/test-stream-readableListening-state.js +parallel/test-stream-readable-needReadable.js +parallel/test-stream-readable-next-no-null.js +parallel/test-stream-readable-no-unneeded-readable.js +parallel/test-stream-readable-object-multi-push-async.js +parallel/test-stream-readable-pause-and-resume.js +parallel/test-stream-readable-readable.js +parallel/test-stream-readable-readable-then-resume.js +parallel/test-stream-readable-reading-readingMore.js +parallel/test-stream-readable-resume-hwm.js +parallel/test-stream-readable-resumeScheduled.js +parallel/test-stream-readable-setEncoding-existing-buffers.js +parallel/test-stream-readable-setEncoding-null.js +parallel/test-stream-readable-strategy-option.js +parallel/test-stream-readable-to-web.js +parallel/test-stream-readable-to-web-termination.js +parallel/test-stream-readable-unpipe-resume.js +parallel/test-stream-readable-unshift.js +parallel/test-stream-readable-with-unimplemented-_read.js +parallel/test-stream-reduce.js +parallel/test-stream-set-default-hwm.js +parallel/test-streams-highwatermark.js +parallel/test-stream-toArray.js +parallel/test-stream-toWeb-allows-server-response.js +parallel/test-stream-transform-callback-twice.js +parallel/test-stream-transform-constructor-set-methods.js +parallel/test-stream-transform-destroy.js +parallel/test-stream-transform-final.js +parallel/test-stream-transform-final-sync.js +parallel/test-stream-transform-flush-data.js +parallel/test-stream-transform-hwm0.js +parallel/test-stream-transform-objectmode-falsey-value.js +parallel/test-stream-transform-split-highwatermark.js +parallel/test-stream-transform-split-objectmode.js +parallel/test-stream-typedarray.js +parallel/test-stream-uint8array.js +parallel/test-stream-unpipe-event.js +parallel/test-stream-unshift-empty-chunk.js +parallel/test-stream-unshift-read-race.js +parallel/test-stream-wrap-drain.js +parallel/test-stream-wrap-encoding.js +parallel/test-stream-wrap.js +parallel/test-stream-writable-aborted.js +parallel/test-stream-writable-change-default-encoding.js +parallel/test-stream-writable-clear-buffer.js +parallel/test-stream-writable-constructor-set-methods.js +parallel/test-stream-writable-decoded-encoding.js +parallel/test-stream-writable-destroy.js +parallel/test-stream-writable-end-cb-error.js +parallel/test-stream-writable-end-cb-uncaught.js +parallel/test-stream-writable-ended-state.js +parallel/test-stream-writable-end-multiple.js +parallel/test-stream-writable-final-async.js +parallel/test-stream-writable-final-destroy.js +parallel/test-stream-writable-final-throw.js +parallel/test-stream-writable-finish-destroyed.js +parallel/test-stream-writable-finished.js +parallel/test-stream-writable-finished-state.js +parallel/test-stream-writable-invalid-chunk.js +parallel/test-stream-writable-needdrain-state.js +parallel/test-stream-writable-null.js +parallel/test-stream-writable-properties.js +parallel/test-stream-writable-samecb-singletick.js +parallel/test-stream-writableState-ending.js +parallel/test-stream-writableState-uncorked-bufferedRequestCount.js +parallel/test-stream-writable-writable.js +parallel/test-stream-writable-write-cb-error.js +parallel/test-stream-writable-write-cb-twice.js +parallel/test-stream-writable-write-error.js +parallel/test-stream-writable-write-writev-finish.js +parallel/test-stream-write-destroy.js +parallel/test-stream-write-drain.js +parallel/test-stream-write-final.js +parallel/test-stream-writev.js +parallel/test-stringbytes-external.js +parallel/test-string-decoder-end.js +parallel/test-string-decoder-fuzz.js +parallel/test-string-decoder.js +parallel/test-structuredClone-global.js +parallel/test-sync-fileread.js +parallel/test-sync-io-option.js +parallel/test-sys.js +parallel/test-tcp-wrap-connect.js +parallel/test-tcp-wrap.js +parallel/test-tcp-wrap-listen.js +parallel/test-tick-processor-arguments.js +parallel/test-tick-processor-version-check.js +parallel/test-timers-active.js +parallel/test-timers-api-refs.js +parallel/test-timers-args.js +parallel/test-timers-clearImmediate-als.js +parallel/test-timers-clearImmediate.js +parallel/test-timers-clear-null-does-not-throw-error.js +parallel/test-timers-clear-object-does-not-throw-error.js +parallel/test-timers-clear-timeout-interval-equivalent.js +parallel/test-timers-destroyed.js +parallel/test-timers-dispose.js +parallel/test-timers-enroll-invalid-msecs.js +parallel/test-timers-enroll-second-time.js +parallel/test-timers-immediate.js +parallel/test-timers-immediate-promisified.js +parallel/test-timers-immediate-queue.js +parallel/test-timers-immediate-queue-throw.js +parallel/test-timers-immediate-unref.js +parallel/test-timers-immediate-unref-nested-once.js +parallel/test-timers-immediate-unref-simple.js +parallel/test-timers-interval-promisified.js +parallel/test-timers-interval-throw.js +parallel/test-timers.js +parallel/test-timers-linked-list.js +parallel/test-timers-max-duration-warning.js +parallel/test-timers-nested.js +parallel/test-timers-next-tick.js +parallel/test-timers-non-integer-delay.js +parallel/test-timers-now.js +parallel/test-timers-ordering.js +parallel/test-timers-process-tampering.js +parallel/test-timers-promises.js +parallel/test-timers-promises-scheduler.js +parallel/test-timers-refresh-in-callback.js +parallel/test-timers-refresh.js +parallel/test-timers-reset-process-domain-on-throw.js +parallel/test-timers-same-timeout-wrong-list-deleted.js +parallel/test-timers-setimmediate-infinite-loop.js +parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js +parallel/test-timers-this.js +parallel/test-timers-throw-when-cb-not-function.js +parallel/test-timers-timeout-promisified.js +parallel/test-timers-timeout-to-interval.js +parallel/test-timers-timeout-with-non-integer.js +parallel/test-timers-to-primitive.js +parallel/test-timers-uncaught-exception.js +parallel/test-timers-unenroll-unref-interval.js +parallel/test-timers-unref-active.js +parallel/test-timers-unrefd-interval-still-fires.js +parallel/test-timers-unrefed-in-beforeexit.js +parallel/test-timers-unrefed-in-callback.js +parallel/test-timers-unref.js +parallel/test-timers-unref-remove-other-unref-timers.js +parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js +parallel/test-timers-unref-throw-then-ref.js +parallel/test-timers-user-call.js +parallel/test-timers-zero-timeout.js +parallel/test-tls-0-dns-altname.js +parallel/test-tls-addca.js +parallel/test-tls-add-context.js +parallel/test-tls-alert-handling.js +parallel/test-tls-alert.js +parallel/test-tls-alpn-server-client.js +parallel/test-tls-async-cb-after-socket-end.js +parallel/test-tls-basic-validations.js +parallel/test-tls-buffersize.js +parallel/test-tls-ca-concat.js +parallel/test-tls-canonical-ip.js +parallel/test-tls-cert-chains-concat.js +parallel/test-tls-cert-chains-in-ca.js +parallel/test-tls-cert-ext-encoding.js +parallel/test-tls-cert-regression.js +parallel/test-tls-check-server-identity.js +parallel/test-tls-cipher-list.js +parallel/test-tls-client-abort2.js +parallel/test-tls-client-abort.js +parallel/test-tls-client-allow-partial-trust-chain.js +parallel/test-tls-client-auth.js +parallel/test-tls-clientcertengine-invalid-arg-type.js +parallel/test-tls-clientcertengine-unsupported.js +parallel/test-tls-client-default-ciphers.js +parallel/test-tls-client-destroy-soon.js +parallel/test-tls-client-getephemeralkeyinfo.js +parallel/test-tls-client-mindhsize.js +parallel/test-tls-client-reject-12.js +parallel/test-tls-client-reject.js +parallel/test-tls-client-renegotiation-13.js +parallel/test-tls-client-renegotiation-limit.js +parallel/test-tls-client-resume-12.js +parallel/test-tls-client-resume.js +parallel/test-tls-client-verify.js +parallel/test-tls-cli-min-max-conflict.js +parallel/test-tls-close-error.js +parallel/test-tls-close-event-after-write.js +parallel/test-tls-close-notify.js +parallel/test-tls-cnnic-whitelist.js +parallel/test-tls-connect-abort-controller.js +parallel/test-tls-connect-address-family.js +parallel/test-tls-connect-allow-half-open-option.js +parallel/test-tls-connect-given-socket.js +parallel/test-tls-connect-hints-option.js +parallel/test-tls-connect-hwm-option.js +parallel/test-tls-connect-memleak.js +parallel/test-tls-connect-no-host.js +parallel/test-tls-connect-pipe.js +parallel/test-tls-connect-secure-context.js +parallel/test-tls-connect-simple.js +parallel/test-tls-connect-stream-writes.js +parallel/test-tls-connect-timeout-option.js +parallel/test-tls-delayed-attach-error.js +parallel/test-tls-delayed-attach.js +parallel/test-tls-destroy-stream-12.js +parallel/test-tls-destroy-stream.js +parallel/test-tls-destroy-whilst-write.js +parallel/test-tls-dhe.js +parallel/test-tls-disable-renegotiation.js +parallel/test-tls-ecdh-auto.js +parallel/test-tls-ecdh.js +parallel/test-tls-ecdh-multiple.js +parallel/test-tls-econnreset.js +parallel/test-tls-empty-sni-context.js +parallel/test-tls-enable-keylog-cli.js +parallel/test-tls-enable-trace-cli.js +parallel/test-tls-enable-trace.js +parallel/test-tls-env-bad-extra-ca.js +parallel/test-tls-env-extra-ca.js +parallel/test-tls-env-extra-ca-no-crypto.js +parallel/test-tls-env-extra-ca-with-options.js +parallel/test-tls-error-servername.js +parallel/test-tls-exportkeyingmaterial.js +parallel/test-tls-external-accessor.js +parallel/test-tls-fast-writing.js +parallel/test-tls-finished.js +parallel/test-tls-friendly-error-message.js +parallel/test-tls-generic-stream.js +parallel/test-tls-getcertificate-x509.js +parallel/test-tls-getcipher.js +parallel/test-tls-getprotocol.js +parallel/test-tls-handshake-error.js +parallel/test-tls-handshake-exception.js +parallel/test-tls-handshake-nohang.js +parallel/test-tls-hello-parser-failure.js +parallel/test-tls-honorcipherorder.js +parallel/test-tls-inception.js +parallel/test-tls-interleave.js +parallel/test-tls-invalid-pfx.js +parallel/test-tls-invoke-queued.js +parallel/test-tls-ip-servername-deprecation.js +parallel/test-tls-js-stream.js +parallel/test-tls-junk-closes-server.js +parallel/test-tls-junk-server.js +parallel/test-tls-keyengine-invalid-arg-type.js +parallel/test-tls-keyengine-unsupported.js +parallel/test-tls-keylog-tlsv13.js +parallel/test-tls-key-mismatch.js +parallel/test-tls-legacy-deprecated.js +parallel/test-tls-legacy-pfx.js +parallel/test-tls-max-send-fragment.js +parallel/test-tls-multi-key.js +parallel/test-tls-multi-pfx.js +parallel/test-tls-multiple-cas-as-string.js +parallel/test-tls-net-connect-prefer-path.js +parallel/test-tls-net-socket-keepalive-12.js +parallel/test-tls-net-socket-keepalive.js +parallel/test-tls-no-cert-required.js +parallel/test-tls-no-rsa-key.js +parallel/test-tls-no-sslv23.js +parallel/test-tls-no-sslv3.js +parallel/test-tls-ocsp-callback.js +parallel/test-tls-on-empty-socket.js +parallel/test-tls-onread-static-buffer.js +parallel/test-tls-options-boolean-check.js +parallel/test-tls-over-http-tunnel.js +parallel/test-tls-passphrase.js +parallel/test-tls-pause.js +parallel/test-tls-peer-certificate-encoding.js +parallel/test-tls-peer-certificate.js +parallel/test-tls-peer-certificate-multi-keys.js +parallel/test-tls-pfx-authorizationerror.js +parallel/test-tls-psk-circuit.js +parallel/test-tls-psk-errors.js +parallel/test-tls-psk-server.js +parallel/test-tls-reduced-SECLEVEL-in-cipher.js +parallel/test-tls-reinitialize-listeners.js +parallel/test-tls-request-timeout.js +parallel/test-tls-retain-handle-no-abort.js +parallel/test-tls-reuse-host-from-socket.js +parallel/test-tls-root-certificates.js +parallel/test-tls-secure-context-usage-order.js +parallel/test-tls-securepair-fiftharg.js +parallel/test-tls-securepair-leak.js +parallel/test-tls-securepair-server.js +parallel/test-tls-secure-session.js +parallel/test-tls-server-capture-rejection.js +parallel/test-tls-server-connection-server.js +parallel/test-tls-server-failed-handshake-emits-clienterror.js +parallel/test-tls-server-parent-constructor-options.js +parallel/test-tls-server-setkeycert.js +parallel/test-tls-server-setoptions-clientcertengine.js +parallel/test-tls-server-verify.js +parallel/test-tls-session-cache.js +parallel/test-tls-set-ciphers-error.js +parallel/test-tls-set-ciphers.js +parallel/test-tls-set-encoding.js +parallel/test-tls-set-secure-context.js +parallel/test-tls-set-sigalgs.js +parallel/test-tls-snicallback-error.js +parallel/test-tls-sni-option.js +parallel/test-tls-sni-server-client.js +parallel/test-tls-sni-servername.js +parallel/test-tls-socket-allow-half-open-option.js +parallel/test-tls-socket-close.js +parallel/test-tls-socket-constructor-alpn-options-parsing.js +parallel/test-tls-socket-default-options.js +parallel/test-tls-socket-destroy.js +parallel/test-tls-socket-failed-handshake-emits-error.js +parallel/test-tls-socket-snicallback-without-server.js +parallel/test-tls-startcom-wosign-whitelist.js +parallel/test-tls-starttls-server.js +parallel/test-tls-streamwrap-buffersize.js +parallel/test-tls-ticket-12.js +parallel/test-tls-ticket-cluster.js +parallel/test-tls-ticket-invalid-arg.js +parallel/test-tls-ticket.js +parallel/test-tls-timeout-server-2.js +parallel/test-tls-timeout-server.js +parallel/test-tls-tlswrap-segfault-2.js +parallel/test-tls-tlswrap-segfault.js +parallel/test-tls-translate-peer-certificate.js +parallel/test-tls-transport-destroy-after-own-gc.js +parallel/test-tls-use-after-free-regression.js +parallel/test-tls-wrap-econnreset.js +parallel/test-tls-wrap-econnreset-localaddress.js +parallel/test-tls-wrap-econnreset-pipe.js +parallel/test-tls-wrap-econnreset-socket.js +parallel/test-tls-wrap-event-emmiter.js +parallel/test-tls-wrap-no-abort.js +parallel/test-tls-wrap-timeout.js +parallel/test-tls-writewrap-leak.js +parallel/test-tls-zero-clear-in.js +parallel/test-tojson-perf_hooks.js +parallel/test-trace-atomic-deprecation.js +parallel/test-trace-atomics-wait.js +parallel/test-trace-env.js +parallel/test-trace-env-stack.js +parallel/test-trace-events-all.js +parallel/test-trace-events-api.js +parallel/test-trace-events-api-worker-disabled.js +parallel/test-trace-events-async-hooks-dynamic.js +parallel/test-trace-events-async-hooks.js +parallel/test-trace-events-async-hooks-worker.js +parallel/test-trace-events-binding.js +parallel/test-trace-events-bootstrap.js +parallel/test-trace-events-category-used.js +parallel/test-trace-events-console.js +parallel/test-trace-events-dynamic-enable.js +parallel/test-trace-events-dynamic-enable-workers-disabled.js +parallel/test-trace-events-environment.js +parallel/test-trace-events-file-pattern.js +parallel/test-trace-events-fs-async.js +parallel/test-trace-events-fs-sync.js +parallel/test-trace-events-get-category-enabled-buffer.js +parallel/test-trace-events-http.js +parallel/test-trace-events-metadata.js +parallel/test-trace-events-net-abstract-socket.js +parallel/test-trace-events-net.js +parallel/test-trace-events-none.js +parallel/test-trace-events-process-exit.js +parallel/test-trace-events-promises.js +parallel/test-trace-events-threadpool.js +parallel/test-trace-events-v8.js +parallel/test-trace-events-vm.js +parallel/test-trace-events-worker-metadata.js +parallel/test-trace-events-worker-metadata-with-name.js +parallel/test-trace-exit.js +parallel/test-trace-exit-stack-limit.js +parallel/test-tracing-no-crash.js +parallel/test-tty-backwards-api.js +parallel/test-tty-stdin-end.js +parallel/test-tty-stdin-pipe.js +parallel/test-ttywrap-invalid-fd.js +parallel/test-ttywrap-stack.js +parallel/test-tz-version.js +parallel/test-unhandled-exception-rethrow-error.js +parallel/test-unhandled-exception-with-worker-inuse.js +parallel/test-unicode-node-options.js +parallel/test-url-domain-ascii-unicode.js +parallel/test-url-fileurltopath.js +parallel/test-url-format-invalid-input.js +parallel/test-url-format.js +parallel/test-url-format-whatwg.js +parallel/test-url-is-url-internal.js +parallel/test-url-parse-format.js +parallel/test-url-parse-invalid-input.js +parallel/test-url-parse-query.js +parallel/test-url-pathtofileurl.js +parallel/test-url-relative.js +parallel/test-url-revokeobjecturl.js +parallel/test-url-urltooptions.js +parallel/test-utf8-scripts.js +parallel/test-util-callbackify.js +parallel/test-util-deprecate-invalid-code.js +parallel/test-util-deprecate.js +parallel/test-util-emit-experimental-warning.js +parallel/test-util-format.js +parallel/test-util-getcallsite.js +parallel/test-util-getcallsites.js +parallel/test-util-inherits.js +parallel/test-util-inspect-getters-accessing-this.js +parallel/test-util-inspect.js +parallel/test-util-inspect-long-running.js +parallel/test-util-inspect-namespace.js +parallel/test-util-inspect-proxy.js +parallel/test-util-internal.js +parallel/test-util-isDeepStrictEqual.js +parallel/test-util.js +parallel/test-util-log.js +parallel/test-util-parse-env.js +parallel/test-util-primordial-monkeypatching.js +parallel/test-util-promisify.js +parallel/test-util-sigint-watchdog.js +parallel/test-util-sleep.js +parallel/test-util-stripvtcontrolcharacters.js +parallel/test-util-styletext.js +parallel/test-util-text-decoder.js +parallel/test-util-types-exists.js +parallel/test-util-types.js +parallel/test-uv-binding-constant.js +parallel/test-uv-errmap.js +parallel/test-uv-errno.js +parallel/test-uv-unmapped-exception.js +parallel/test-v8-collect-gc-profile-exit-before-stop.js +parallel/test-v8-collect-gc-profile-in-worker.js +parallel/test-v8-collect-gc-profile.js +parallel/test-v8-coverage.js +parallel/test-v8-deserialize-buffer.js +parallel/test-v8-flag-pool-size-0.js +parallel/test-v8-flags.js +parallel/test-v8-flag-type-check.js +parallel/test-v8-getheapsnapshot-twice.js +parallel/test-v8-global-setter.js +parallel/test-v8-query-objects.js +parallel/test-v8-serdes.js +parallel/test-v8-serialize-leak.js +parallel/test-v8-startup-snapshot-api.js +parallel/test-v8-stats.js +parallel/test-v8-stop-coverage.js +parallel/test-v8-take-coverage.js +parallel/test-v8-take-coverage-noop.js +parallel/test-v8-version-tag.js +parallel/test-validators.js +parallel/test-vfs.js +parallel/test-vm-access-process-env.js +parallel/test-vm-api-handles-getter-errors.js +parallel/test-vm-attributes-property-not-on-sandbox.js +parallel/test-vm-basic.js +parallel/test-vm-cached-data.js +parallel/test-vm-codegen.js +parallel/test-vm-context-async-script.js +parallel/test-vm-context-dont-contextify.js +parallel/test-vm-context.js +parallel/test-vm-context-property-forwarding.js +parallel/test-vm-create-and-run-in-context.js +parallel/test-vm-createcacheddata.js +parallel/test-vm-create-context-accessors.js +parallel/test-vm-create-context-arg.js +parallel/test-vm-create-context-circular-reference.js +parallel/test-vm-cross-context.js +parallel/test-vm-data-property-writable.js +parallel/test-vm-deleting-property.js +parallel/test-vm-dynamic-import-callback-missing-flag.js +parallel/test-vm-function-declaration.js +parallel/test-vm-function-redefinition.js +parallel/test-vm-getters.js +parallel/test-vm-global-assignment.js +parallel/test-vm-global-configurable-properties.js +parallel/test-vm-global-define-property.js +parallel/test-vm-global-get-own.js +parallel/test-vm-global-identity.js +parallel/test-vm-global-non-writable-properties.js +parallel/test-vm-global-property-enumerator.js +parallel/test-vm-global-property-interceptors.js +parallel/test-vm-global-property-prototype.js +parallel/test-vm-global-setter.js +parallel/test-vm-harmony-symbols.js +parallel/test-vm-indexed-properties.js +parallel/test-vm-inherited_properties.js +parallel/test-vm-is-context.js +parallel/test-vm-low-stack-space.js +parallel/test-vm-measure-memory.js +parallel/test-vm-measure-memory-lazy.js +parallel/test-vm-measure-memory-multi-context.js +parallel/test-vm-module-basic.js +parallel/test-vm-module-cached-data.js +parallel/test-vm-module-dynamic-import.js +parallel/test-vm-module-dynamic-namespace.js +parallel/test-vm-module-errors.js +parallel/test-vm-module-import-meta.js +parallel/test-vm-module-link.js +parallel/test-vm-module-reevaluate.js +parallel/test-vm-module-synthetic.js +parallel/test-vm-new-script-new-context.js +parallel/test-vm-new-script-this-context.js +parallel/test-vm-no-dynamic-import-callback.js +parallel/test-vm-not-strict.js +parallel/test-vm-options-validation.js +parallel/test-vm-ownkeys.js +parallel/test-vm-ownpropertynames.js +parallel/test-vm-ownpropertysymbols.js +parallel/test-vm-parse-abort-on-uncaught-exception.js +parallel/test-vm-preserves-property.js +parallel/test-vm-property-not-on-sandbox.js +parallel/test-vm-proxies.js +parallel/test-vm-proxy-failure-CP.js +parallel/test-vm-run-in-new-context.js +parallel/test-vm-script-throw-in-tostring.js +parallel/test-vm-set-property-proxy.js +parallel/test-vm-set-proto-null-on-globalthis.js +parallel/test-vm-sigint-existing-handler.js +parallel/test-vm-sigint.js +parallel/test-vm-source-map-url.js +parallel/test-vm-static-this.js +parallel/test-vm-strict-assign.js +parallel/test-vm-strict-mode.js +parallel/test-vm-symbols.js +parallel/test-vm-syntax-error-message.js +parallel/test-vm-syntax-error-stderr.js +parallel/test-vm-timeout-escape-promise-2.js +parallel/test-vm-timeout-escape-promise.js +parallel/test-vm-timeout-escape-promise-module.js +parallel/test-vm-timeout.js +parallel/test-warn-sigprof.js +parallel/test-warn-stream-wrap.js +parallel/test-weakref.js +parallel/test-webcrypto-constructors.js +parallel/test-webcrypto-cryptokey-workers.js +parallel/test-webcrypto-derivebits-cfrg.js +parallel/test-webcrypto-derivebits-ecdh.js +parallel/test-webcrypto-derivebits-hkdf.js +parallel/test-webcrypto-derivebits.js +parallel/test-webcrypto-derivekey-cfrg.js +parallel/test-webcrypto-derivekey-ecdh.js +parallel/test-webcrypto-derivekey.js +parallel/test-webcrypto-digest.js +parallel/test-webcrypto-encrypt-decrypt-aes.js +parallel/test-webcrypto-encrypt-decrypt.js +parallel/test-webcrypto-encrypt-decrypt-rsa.js +parallel/test-webcrypto-export-import-cfrg.js +parallel/test-webcrypto-export-import-ec.js +parallel/test-webcrypto-export-import.js +parallel/test-webcrypto-export-import-rsa.js +parallel/test-webcrypto-getRandomValues.js +parallel/test-webcrypto-keygen.js +parallel/test-webcrypto-random.js +parallel/test-webcrypto-sign-verify-eddsa.js +parallel/test-webcrypto-sign-verify-hmac.js +parallel/test-webcrypto-sign-verify.js +parallel/test-webcrypto-util.js +parallel/test-webcrypto-webidl.js +parallel/test-webcrypto-wrap-unwrap.js +parallel/test-websocket-disabled.js +parallel/test-websocket.js +parallel/test-webstorage.js +parallel/test-webstream-encoding-inspect.js +parallel/test-webstream-readable-from.js +parallel/test-webstream-readablestream-pipeto.js +parallel/test-webstreams-abort-controller.js +parallel/test-webstreams-clone-unref.js +parallel/test-webstreams-compose.js +parallel/test-webstreams-finished.js +parallel/test-webstreams-pipeline.js +parallel/test-webstream-string-tag.js +parallel/test-whatwg-encoding-custom-api-basics.js +parallel/test-whatwg-encoding-custom-fatal-streaming.js +parallel/test-whatwg-encoding-custom-internals.js +parallel/test-whatwg-encoding-custom-interop.js +parallel/test-whatwg-encoding-custom-textdecoder-api-invalid-label.js +parallel/test-whatwg-encoding-custom-textdecoder-fatal.js +parallel/test-whatwg-encoding-custom-textdecoder-ignorebom.js +parallel/test-whatwg-encoding-custom-textdecoder-invalid-arg.js +parallel/test-whatwg-encoding-custom-textdecoder.js +parallel/test-whatwg-encoding-custom-textdecoder-streaming.js +parallel/test-whatwg-encoding-custom-textdecoder-utf16-surrogates.js +parallel/test-whatwg-events-add-event-listener-options-passive.js +parallel/test-whatwg-events-add-event-listener-options-signal.js +parallel/test-whatwg-events-customevent.js +parallel/test-whatwg-events-event-constructors.js +parallel/test-whatwg-events-eventtarget-this-of-listener.js +parallel/test-whatwg-readablebytestream-bad-buffers-and-views.js +parallel/test-whatwg-readablebytestreambyob.js +parallel/test-whatwg-readablebytestream.js +parallel/test-whatwg-readablestream.js +parallel/test-whatwg-transformstream.js +parallel/test-whatwg-url-canparse.js +parallel/test-whatwg-url-custom-deepequal.js +parallel/test-whatwg-url-custom-global.js +parallel/test-whatwg-url-custom-href-side-effect.js +parallel/test-whatwg-url-custom-inspect.js +parallel/test-whatwg-url-custom-parsing.js +parallel/test-whatwg-url-custom-properties.js +parallel/test-whatwg-url-custom-searchparams-append.js +parallel/test-whatwg-url-custom-searchparams-constructor.js +parallel/test-whatwg-url-custom-searchparams-delete.js +parallel/test-whatwg-url-custom-searchparams-entries.js +parallel/test-whatwg-url-custom-searchparams-foreach.js +parallel/test-whatwg-url-custom-searchparams-getall.js +parallel/test-whatwg-url-custom-searchparams-get.js +parallel/test-whatwg-url-custom-searchparams-has.js +parallel/test-whatwg-url-custom-searchparams-inspect.js +parallel/test-whatwg-url-custom-searchparams.js +parallel/test-whatwg-url-custom-searchparams-keys.js +parallel/test-whatwg-url-custom-searchparams-set.js +parallel/test-whatwg-url-custom-searchparams-sort.js +parallel/test-whatwg-url-custom-searchparams-stringifier.js +parallel/test-whatwg-url-custom-searchparams-values.js +parallel/test-whatwg-url-custom-setters.js +parallel/test-whatwg-url-custom-tostringtag.js +parallel/test-whatwg-url-invalidthis.js +parallel/test-whatwg-url-override-hostname.js +parallel/test-whatwg-url-properties.js +parallel/test-whatwg-webstreams-adapters-streambase.js +parallel/test-whatwg-webstreams-adapters-to-readablestream.js +parallel/test-whatwg-webstreams-adapters-to-readablewritablepair.js +parallel/test-whatwg-webstreams-adapters-to-streamduplex.js +parallel/test-whatwg-webstreams-adapters-to-streamreadable.js +parallel/test-whatwg-webstreams-adapters-to-streamwritable.js +parallel/test-whatwg-webstreams-adapters-to-writablestream.js +parallel/test-whatwg-webstreams-compression.js +parallel/test-whatwg-webstreams-coverage.js +parallel/test-whatwg-webstreams-encoding.js +parallel/test-whatwg-webstreams-transfer.js +parallel/test-whatwg-writablestream.js +parallel/test-windows-abort-exitcode.js +parallel/test-windows-failed-heap-allocation.js +parallel/test-worker-abort-on-uncaught-exception.js +parallel/test-worker-abort-on-uncaught-exception-terminate.js +parallel/test-worker-arraybuffer-zerofill.js +parallel/test-worker-beforeexit-throw-exit.js +parallel/test-worker-broadcastchannel.js +parallel/test-worker-broadcastchannel-wpt.js +parallel/test-worker-cjs-workerdata.js +parallel/test-worker-cleanexit-with-js.js +parallel/test-worker-cleanexit-with-moduleload.js +parallel/test-worker-cleanup-handles.js +parallel/test-worker-cli-options.js +parallel/test-worker-console-listeners.js +parallel/test-worker-crypto-sign-transfer-result.js +parallel/test-worker-data-url.js +parallel/test-worker-debug.js +parallel/test-worker-dns-terminate-during-query.js +parallel/test-worker-dns-terminate.js +parallel/test-worker-environmentdata.js +parallel/test-worker-error-stack-getter-throws.js +parallel/test-worker-esm-exit.js +parallel/test-worker-esm-missing-main.js +parallel/test-worker-esmodule.js +parallel/test-worker-eval-typescript.js +parallel/test-worker-event.js +parallel/test-worker-execargv-invalid.js +parallel/test-worker-execargv.js +parallel/test-worker-exit-code.js +parallel/test-worker-exit-event-error.js +parallel/test-worker-exit-from-uncaught-exception.js +parallel/test-worker-exit-heapsnapshot.js +parallel/test-worker-fs-stat-watcher.js +parallel/test-worker-hasref.js +parallel/test-worker-heapdump-failure.js +parallel/test-worker-heap-snapshot.js +parallel/test-worker-http2-generic-streams-terminate.js +parallel/test-worker-http2-stream-terminate.js +parallel/test-worker-init-failure.js +parallel/test-worker-invalid-workerdata.js +parallel/test-worker.js +parallel/test-worker-load-file-with-extension-other-than-js.js +parallel/test-worker-memory.js +parallel/test-worker-message-channel.js +parallel/test-worker-message-channel-sharedarraybuffer.js +parallel/test-worker-message-event.js +parallel/test-worker-message-mark-as-uncloneable.js +parallel/test-worker-message-not-serializable.js +parallel/test-worker-message-port-arraybuffer.js +parallel/test-worker-message-port-close.js +parallel/test-worker-message-port-close-while-receiving.js +parallel/test-worker-message-port-constructor.js +parallel/test-worker-message-port-drain.js +parallel/test-worker-messageport-hasref.js +parallel/test-worker-message-port-infinite-message-loop.js +parallel/test-worker-message-port-inspect-during-init-hook.js +parallel/test-worker-message-port.js +parallel/test-worker-message-port-jstransferable-nested-untransferable.js +parallel/test-worker-message-port-message-before-close.js +parallel/test-worker-message-port-message-port-transferring.js +parallel/test-worker-message-port-move.js +parallel/test-worker-message-port-multiple-sharedarraybuffers.js +parallel/test-worker-message-port-receive-message.js +parallel/test-worker-message-port-terminate-transfer-list.js +parallel/test-worker-message-port-transfer-closed.js +parallel/test-worker-message-port-transfer-duplicate.js +parallel/test-worker-message-port-transfer-fake-js-transferable-internal.js +parallel/test-worker-message-port-transfer-fake-js-transferable.js +parallel/test-worker-message-port-transfer-filehandle.js +parallel/test-worker-message-port-transfer-native.js +parallel/test-worker-message-port-transfer-self.js +parallel/test-worker-message-port-transfer-target.js +parallel/test-worker-message-port-transfer-terminate.js +parallel/test-worker-message-port-wasm-module.js +parallel/test-worker-message-port-wasm-threads.js +parallel/test-worker-message-transfer-port-mark-as-untransferable.js +parallel/test-worker-message-type-unknown.js +parallel/test-worker-messaging-errors-handler.js +parallel/test-worker-messaging-errors-invalid.js +parallel/test-worker-messaging-errors-timeout.js +parallel/test-worker-messaging.js +parallel/test-worker-mjs-workerdata.js +parallel/test-worker-name.js +parallel/test-worker-nearheaplimit-deadlock.js +parallel/test-worker-nested-on-process-exit.js +parallel/test-worker-nested-uncaught.js +parallel/test-worker-nexttick-terminate.js +parallel/test-worker-node-options.js +parallel/test-worker-non-fatal-uncaught-exception.js +parallel/test-worker-no-sab.js +parallel/test-worker-no-stdin-stdout-interaction.js +parallel/test-worker-onmessage.js +parallel/test-worker-onmessage-not-a-function.js +parallel/test-worker-on-process-exit.js +parallel/test-worker-parent-port-ref.js +parallel/test-worker-process-argv.js +parallel/test-worker-process-cwd.js +parallel/test-worker-process-env.js +parallel/test-worker-process-env-shared.js +parallel/test-worker-process-exit-async-module.js +parallel/test-worker-ref.js +parallel/test-worker-ref-onexit.js +parallel/test-worker-relative-path-double-dot.js +parallel/test-worker-relative-path.js +parallel/test-worker-resource-limits.js +parallel/test-worker-safe-getters.js +parallel/test-worker-sharedarraybuffer-from-worker-thread.js +parallel/test-worker-stack-overflow.js +parallel/test-worker-stack-overflow-stack-size.js +parallel/test-worker-stdio-flush-inflight.js +parallel/test-worker-stdio-flush.js +parallel/test-worker-stdio-from-preload-module.js +parallel/test-worker-stdio.js +parallel/test-worker-syntax-error-file.js +parallel/test-worker-syntax-error.js +parallel/test-worker-terminate-http2-respond-with-file.js +parallel/test-worker-terminate-microtask-loop.js +parallel/test-worker-terminate-nested.js +parallel/test-worker-terminate-null-handler.js +parallel/test-worker-terminate-ref-public-port.js +parallel/test-worker-terminate-source-map.js +parallel/test-worker-terminate-timers.js +parallel/test-worker-terminate-unrefed.js +parallel/test-worker-track-unmanaged-fds.js +parallel/test-worker-type-check.js +parallel/test-worker-uncaught-exception-async.js +parallel/test-worker-uncaught-exception.js +parallel/test-worker-unref-from-message-during-exit.js +parallel/test-worker-unsupported-path.js +parallel/test-worker-unsupported-things.js +parallel/test-worker-vm-context-terminate.js +parallel/test-worker-voluntarily-exit-followed-by-addition.js +parallel/test-worker-voluntarily-exit-followed-by-throw.js +parallel/test-worker-workerdata-messageport.js +parallel/test-worker-workerdata-sharedarraybuffer.js +parallel/test-wrap-js-stream-destroy.js +parallel/test-wrap-js-stream-duplex.js +parallel/test-wrap-js-stream-exceptions.js +parallel/test-wrap-js-stream-read-stop.js +parallel/test-x509-escaping.js +parallel/test-zlib-brotli-16GB.js +parallel/test-zlib-brotli-flush.js +parallel/test-zlib-brotli-from-brotli.js +parallel/test-zlib-brotli-from-string.js +parallel/test-zlib-brotli.js +parallel/test-zlib-brotli-kmaxlength-rangeerror.js +parallel/test-zlib-bytes-read.js +parallel/test-zlib-close-after-error.js +parallel/test-zlib-close-after-write.js +parallel/test-zlib-close-in-ondata.js +parallel/test-zlib-const.js +parallel/test-zlib-convenience-methods.js +parallel/test-zlib-crc32.js +parallel/test-zlib-create-raw.js +parallel/test-zlib-deflate-constructors.js +parallel/test-zlib-deflate-raw-inherits.js +parallel/test-zlib-destroy.js +parallel/test-zlib-destroy-pipe.js +parallel/test-zlib-dictionary-fail.js +parallel/test-zlib-dictionary.js +parallel/test-zlib-empty-buffer.js +parallel/test-zlib-failed-init.js +parallel/test-zlib-flush-drain.js +parallel/test-zlib-flush-drain-longblock.js +parallel/test-zlib-flush-flags.js +parallel/test-zlib-flush.js +parallel/test-zlib-flush-write-sync-interleaved.js +parallel/test-zlib-from-concatenated-gzip.js +parallel/test-zlib-from-gzip.js +parallel/test-zlib-from-gzip-with-trailing-garbage.js +parallel/test-zlib-from-string.js +parallel/test-zlib-invalid-arg-value-brotli-compress.js +parallel/test-zlib-invalid-input.js +parallel/test-zlib-invalid-input-memory.js +parallel/test-zlib.js +parallel/test-zlib-kmaxlength-rangeerror.js +parallel/test-zlib-maxOutputLength.js +parallel/test-zlib-no-stream.js +parallel/test-zlib-not-string-or-buffer.js +parallel/test-zlib-object-write.js +parallel/test-zlib-params.js +parallel/test-zlib-premature-end.js +parallel/test-zlib-random-byte-pipes.js +parallel/test-zlib-reset-before-write.js +parallel/test-zlib-sync-no-event.js +parallel/test-zlib-truncated.js +parallel/test-zlib-unused-weak.js +parallel/test-zlib-unzip-one-byte-chunks.js +parallel/test-zlib-write-after-close.js +parallel/test-zlib-write-after-end.js +parallel/test-zlib-write-after-flush.js +parallel/test-zlib-zero-byte.js +parallel/test-zlib-zero-windowBits.js +pseudo-tty/console_colors.js +pseudo-tty/console-dumb-tty.js +pseudo-tty/no_dropped_stdio.js +pseudo-tty/no_interleaved_stdio.js +pseudo-tty/ref_keeps_node_running.js +pseudo-tty/repl-dumb-tty.js