Commit 50ce73fe07b for nodejs

commit 50ce73fe07b95b3e08160c7f2a592f87b62212cc
Author: Node.js GitHub Bot <github-bot@iojs.org>
Date:   Wed Nov 11 12:21:27 2026 -0500

    deps: update nghttp3 to 1.19.0

    PR-URL: https://github.com/nodejs/node/pull/67333
    Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
    Reviewed-By: Tim Perry <pimterry@gmail.com>

diff --git a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h
index d3dd9217d4b..77ae851ae59 100644
--- a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h
+++ b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h
@@ -1871,12 +1871,13 @@ typedef struct nghttp3_settings {
      NGHTTP3_SETTINGS_V3. */
   /**
    * :member:`glitch_ratelim_burst` is the maximum number of tokens
-   * available to "glitch" rate limiter.  "glitch" is a suspicious
-   * activity from a remote endpoint.  If detected, certain amount of
-   * tokens are consumed.  If no tokens are available to consume, the
-   * connection is closed.  The rate of token generation is specified
-   * by :member:`glitch_ratelim_rate`.  This feature is enabled only
-   * when `nghttp3_conn_read_stream2` is used.
+   * available to "glitch" rate limiter.  It is clamped to UINT64_MAX
+   * / NGHTTP3_SECONDS.  "glitch" is a suspicious activity from a
+   * remote endpoint.  If detected, certain amount of tokens are
+   * consumed.  If no tokens are available to consume, the connection
+   * is closed.  The rate of token generation is specified by
+   * :member:`glitch_ratelim_rate`.  This feature is enabled only when
+   * `nghttp3_conn_read_stream2` is used.
    *
    * .. version-added:: 1.12.0
    */
@@ -3089,6 +3090,8 @@ typedef struct nghttp3_data_reader {
  *     Stream has already been opened.
  * :macro:`NGHTTP3_ERR_NOMEM`
  *     Out of memory.
+ * :macro:`NGHTTP3_ERR_INVALID_ARGUMENT`
+ *     The required memory for |nva| of length |nvlen| is too large.
  */
 NGHTTP3_EXTERN int nghttp3_conn_submit_request(
   nghttp3_conn *conn, int64_t stream_id, const nghttp3_nv *nva, size_t nvlen,
@@ -3108,6 +3111,8 @@ NGHTTP3_EXTERN int nghttp3_conn_submit_request(
  *     Stream not found
  * :macro:`NGHTTP3_ERR_NOMEM`
  *     Out of memory.
+ * :macro:`NGHTTP3_ERR_INVALID_ARGUMENT`
+ *     The required memory for |nva| of length |nvlen| is too large.
  */
 NGHTTP3_EXTERN int nghttp3_conn_submit_info(nghttp3_conn *conn,
                                             int64_t stream_id,
@@ -3130,6 +3135,8 @@ NGHTTP3_EXTERN int nghttp3_conn_submit_info(nghttp3_conn *conn,
  *     Stream not found
  * :macro:`NGHTTP3_ERR_NOMEM`
  *     Out of memory.
+ * :macro:`NGHTTP3_ERR_INVALID_ARGUMENT`
+ *     The required memory for |nva| of length |nvlen| is too large.
  */
 NGHTTP3_EXTERN int nghttp3_conn_submit_response(nghttp3_conn *conn,
                                                 int64_t stream_id,
@@ -3154,6 +3161,8 @@ NGHTTP3_EXTERN int nghttp3_conn_submit_response(nghttp3_conn *conn,
  *     Application has already submitted fin to stream.
  * :macro:`NGHTTP3_ERR_NOMEM`
  *     Out of memory.
+ * :macro:`NGHTTP3_ERR_INVALID_ARGUMENT`
+ *     The required memory for |nva| of length |nvlen| is too large.
  */
 NGHTTP3_EXTERN int nghttp3_conn_submit_trailers(nghttp3_conn *conn,
                                                 int64_t stream_id,
diff --git a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h
index adb41c1c7b2..f362bd4f6ba 100644
--- a/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h
+++ b/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h
@@ -31,7 +31,7 @@
  *
  * Version number of the nghttp3 library release.
  */
-#define NGHTTP3_VERSION "1.18.0"
+#define NGHTTP3_VERSION "1.19.0"

 /**
  * @macro
@@ -41,6 +41,6 @@
  * number, 8 bits for minor and 8 bits for patch. Version 1.2.3
  * becomes 0x010203.
  */
-#define NGHTTP3_VERSION_NUM 0x011200
+#define NGHTTP3_VERSION_NUM 0x011300

 #endif /* !defined(NGHTTP3_VERSION_H) */
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_balloc.c b/deps/ngtcp2/nghttp3/lib/nghttp3_balloc.c
index 43631063334..7750263242e 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_balloc.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_balloc.c
@@ -67,7 +67,7 @@ int nghttp3_balloc_get(nghttp3_balloc *balloc, void **pbuf, size_t n) {

   if (nghttp3_buf_left(&balloc->buf) < n) {
     p = nghttp3_mem_malloc(balloc->mem,
-                           sizeof(nghttp3_memblock_hd) + 0x8U + balloc->blklen);
+                           sizeof(nghttp3_memblock_hd) + 0xFU + balloc->blklen);
     if (p == NULL) {
       return NGHTTP3_ERR_NOMEM;
     }
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c b/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c
index 8c33ccdb153..7c3296cd1ef 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_buf.c
@@ -25,13 +25,15 @@
  */
 #include "nghttp3_buf.h"

-void nghttp3_buf_init(nghttp3_buf *buf) {
-  buf->begin = buf->end = buf->pos = buf->last = NULL;
-}
+void nghttp3_buf_init(nghttp3_buf *buf) { *buf = (nghttp3_buf){0}; }

 void nghttp3_buf_wrap_init(nghttp3_buf *buf, uint8_t *src, size_t len) {
-  buf->begin = buf->pos = buf->last = src;
-  buf->end = buf->begin + len;
+  *buf = (nghttp3_buf){
+    .begin = src,
+    .end = src + len,
+    .pos = src,
+    .last = src,
+  };
 }

 void nghttp3_buf_free(nghttp3_buf *buf, const nghttp3_mem *mem) {
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c
index 04b50ac3b63..8b15fb743bd 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_conn.c
@@ -555,13 +555,14 @@ nghttp3_ssize nghttp3_conn_read_stream2(nghttp3_conn *conn, int64_t stream_id,
     return 0;
   }

+  if (fin) {
+    stream->flags |= NGHTTP3_STREAM_FLAG_READ_EOF;
+  }
+
   if (nghttp3_stream_uni(stream_id)) {
     return nghttp3_conn_read_uni(conn, stream, src, srclen, fin, ts);
   }

-  if (fin) {
-    stream->flags |= NGHTTP3_STREAM_FLAG_READ_EOF;
-  }
   return nghttp3_conn_read_bidi(conn, &bidi_nproc, stream, src, srclen, fin,
                                 ts);
 }
@@ -1126,6 +1127,13 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
         break;
       }

+      /* Apply buffer limits here even if everything is in the input
+         buffer. */
+      if (rstate->left > sizeof(conn->rx.pri_fieldbuf)) {
+        rstate->state = NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME;
+        break;
+      }
+
       conn->rx.pri_fieldbuflen = 0;

       rstate->state = NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE;
@@ -1141,22 +1149,12 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
       len = (size_t)nghttp3_min(rstate->left, (uint64_t)(end - p));
       assert(len > 0);
       if (conn->rx.pri_fieldbuflen == 0 && rstate->left == len) {
-        /* Everything is in the input buffer.  Apply same length
-           limit we impose when buffering the field. */
-        if (len > sizeof(conn->rx.pri_fieldbuf)) {
-          busy = 1;
-          rstate->state = NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME;
-          break;
-        }
-
+        /* Everything is in the input buffer. */
         pri_field_value = p;
         pri_field_valuelen = len;
-      } else if (len + conn->rx.pri_fieldbuflen >
-                 sizeof(conn->rx.pri_fieldbuf)) {
-        busy = 1;
-        rstate->state = NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME;
-        break;
       } else {
+        assert(len + conn->rx.pri_fieldbuflen <= sizeof(conn->rx.pri_fieldbuf));
+
         memcpy(conn->rx.pri_fieldbuf + conn->rx.pri_fieldbuflen, p, len);
         conn->rx.pri_fieldbuflen += len;

@@ -1975,6 +1973,12 @@ int nghttp3_conn_on_settings_entry_received(nghttp3_conn *conn,
       break;
     }

+#if SIZE_MAX < UINT64_MAX
+    if (ent->value > SIZE_MAX) {
+      return NGHTTP3_ERR_H3_SETTINGS_ERROR;
+    }
+#endif /* SIZE_MAX < UINT64_MAX */
+
     dest->qpack_max_dtable_capacity = (size_t)ent->value;

     nghttp3_qpack_encoder_set_max_dtable_capacity(&conn->qenc,
@@ -1989,6 +1993,12 @@ int nghttp3_conn_on_settings_entry_received(nghttp3_conn *conn,
       break;
     }

+#if SIZE_MAX < UINT64_MAX
+    if (ent->value > SIZE_MAX) {
+      return NGHTTP3_ERR_H3_SETTINGS_ERROR;
+    }
+#endif /* SIZE_MAX < UINT64_MAX */
+
     dest->qpack_blocked_streams = (size_t)ent->value;

     nghttp3_qpack_encoder_set_max_blocked_streams(
@@ -2957,6 +2967,8 @@ int nghttp3_conn_set_client_stream_priority(nghttp3_conn *conn,
     memcpy(buf, data, datalen);
   }

+  assert(conn->tx.ctrl);
+
   rv = nghttp3_stream_frq_emplace(conn->tx.ctrl, &fr);
   if (rv != 0) {
     nghttp3_mem_free(conn->mem, buf);
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_frame.c b/deps/ngtcp2/nghttp3/lib/nghttp3_frame.c
index 2efba7472c2..aea874fff4d 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_frame.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_frame.c
@@ -136,8 +136,8 @@ size_t nghttp3_frame_write_origin_len(uint64_t *ppayloadlen,
 int nghttp3_nva_copy(nghttp3_nv **pnva, const nghttp3_nv *nva, size_t nvlen,
                      const nghttp3_mem *mem) {
   size_t i;
-  uint8_t *data = NULL;
-  size_t buflen = 0;
+  uint8_t *data;
+  size_t buflen;
   nghttp3_nv *p;

   if (nvlen == 0) {
@@ -146,18 +146,32 @@ int nghttp3_nva_copy(nghttp3_nv **pnva, const nghttp3_nv *nva, size_t nvlen,
     return 0;
   }

+  if (sizeof(nghttp3_nv) > SIZE_MAX / nvlen) {
+    return NGHTTP3_ERR_INVALID_ARGUMENT;
+  }
+
+  buflen = sizeof(nghttp3_nv) * nvlen;
+
   for (i = 0; i < nvlen; ++i) {
     /* + 1 for null-termination */
     if ((nva[i].flags & NGHTTP3_NV_FLAG_NO_COPY_NAME) == 0) {
+      if (nva[i].namelen == SIZE_MAX ||
+          buflen > SIZE_MAX - nva[i].namelen - 1) {
+        return NGHTTP3_ERR_INVALID_ARGUMENT;
+      }
+
       buflen += nva[i].namelen + 1;
     }
     if ((nva[i].flags & NGHTTP3_NV_FLAG_NO_COPY_VALUE) == 0) {
+      if (nva[i].valuelen == SIZE_MAX ||
+          buflen > SIZE_MAX - nva[i].valuelen - 1) {
+        return NGHTTP3_ERR_INVALID_ARGUMENT;
+      }
+
       buflen += nva[i].valuelen + 1;
     }
   }

-  buflen += sizeof(nghttp3_nv) * nvlen;
-
   *pnva = nghttp3_mem_malloc(mem, buflen);

   if (*pnva == NULL) {
@@ -169,30 +183,28 @@ int nghttp3_nva_copy(nghttp3_nv **pnva, const nghttp3_nv *nva, size_t nvlen,

   for (i = 0; i < nvlen; ++i) {
     p->flags = nva[i].flags;
+    p->namelen = nva[i].namelen;
+    p->valuelen = nva[i].valuelen;

     if (nva[i].flags & NGHTTP3_NV_FLAG_NO_COPY_NAME) {
       p->name = nva[i].name;
-      p->namelen = nva[i].namelen;
     } else {
       if (nva[i].namelen) {
         memcpy(data, nva[i].name, nva[i].namelen);
         nghttp3_downcase(data, nva[i].namelen);
       }
       p->name = data;
-      p->namelen = nva[i].namelen;
       data[p->namelen] = '\0';
       data += nva[i].namelen + 1;
     }

     if (nva[i].flags & NGHTTP3_NV_FLAG_NO_COPY_VALUE) {
       p->value = nva[i].value;
-      p->valuelen = nva[i].valuelen;
     } else {
       if (nva[i].valuelen) {
         memcpy(data, nva[i].value, nva[i].valuelen);
       }
       p->value = data;
-      p->valuelen = nva[i].valuelen;
       data[p->valuelen] = '\0';
       data += nva[i].valuelen + 1;
     }
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_frame.h b/deps/ngtcp2/nghttp3/lib/nghttp3_frame.h
index 7806cadbcf5..fee30cb56d7 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_frame.h
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_frame.h
@@ -247,6 +247,8 @@ size_t nghttp3_frame_write_origin_len(uint64_t *ppayloadlen,
  *
  * NGHTTP3_ERR_NOMEM
  *     Out of memory.
+ * NGHTTP3_ERR_INVALID_ARGUMENT
+ *     The required memory for |nva| of length |nvlen| is too large.
  */
 int nghttp3_nva_copy(nghttp3_nv **pnva, const nghttp3_nv *nva, size_t nvlen,
                      const nghttp3_mem *mem);
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_map.c b/deps/ngtcp2/nghttp3/lib/nghttp3_map.c
index 7858d4cc3eb..eae7c4d8dd4 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_map.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_map.c
@@ -31,6 +31,7 @@
 #include <stdio.h>

 #include "nghttp3_conv.h"
+#include "nghttp3_macro.h"

 #define NGHTTP3_INITIAL_HASHBITS 4

@@ -75,18 +76,19 @@ int nghttp3_map_each(const nghttp3_map *map, int (*func)(void *data, void *ptr),
   return 0;
 }

-/* Hasher from
-   https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
-   to maximize the output's sensitivity to all input bits. */
-#define NGHTTP3_MAP_HASHER 0xF1357AEA2E62A9C5ULL
-/* 64-bit Fibonacci hashing constant, Golden Ratio constant, to get
-   the high bits with the good distribution. */
-#define NGHTTP3_MAP_FIBO 0x9E3779B97F4A7C15ULL
+/* 64-bit finalizer (fmix64) from MurmurHash3 to maximize the output's
+   sensitivity to all input bits. */
+#define NGHTTP3_MAP_HASHER1 0xFF51AFD7ED558CCDULL
+#define NGHTTP3_MAP_HASHER2 0xC4CEB9FE1A85EC53ULL

 static size_t map_index(const nghttp3_map *map, nghttp3_map_key_type key) {
-  key += map->seed;
-  key *= NGHTTP3_MAP_HASHER;
-  return (size_t)((key * NGHTTP3_MAP_FIBO) >> (64 - map->hashbits));
+  key ^= map->seed;
+  key ^= key >> 33;
+  key *= NGHTTP3_MAP_HASHER1;
+  key ^= key >> 33;
+  key *= NGHTTP3_MAP_HASHER2;
+  key ^= key >> 33;
+  return (size_t)(key >> (64 - map->hashbits));
 }

 #ifndef WIN32
@@ -108,17 +110,17 @@ void nghttp3_map_print_distance(const nghttp3_map *map) {
     }

     idx = map_index(map, map->keys[i]);
-    fprintf(stderr, "@%zu key=%" PRIu64 " base=%zu distance=%u\n", i,
+    fprintf(stderr, "@%zu key=%" PRIu64 " base=%zu distance=%zu\n", i,
             map->keys[i], idx, map->psl[i] - 1);
   }
 }
 #endif /* !defined(WIN32) */

 static void map_set_entry(nghttp3_map *map, size_t idx,
-                          nghttp3_map_key_type key, void *data, size_t psl) {
+                          nghttp3_map_key_type key, size_t psl, void *data) {
   map->keys[idx] = key;
+  map->psl[idx] = psl;
   map->data[idx] = data;
-  map->psl[idx] = (uint8_t)psl;
 }

 #define NGHTTP3_SWAP(TYPE, A, B)                                               \
@@ -130,15 +132,15 @@ static void map_set_entry(nghttp3_map *map, size_t idx,
   } while (0)

 /*
- * map_insert inserts |key| and |data| to |map|, and returns the index
- * where the pair is stored if it succeeds.  Otherwise, it returns one
- * of the following negative error codes:
+ * map_insert inserts |key| and |data| to |map|.
+ *
+ * It returns 0 if it succeeds, or one of the following negative error
+ * codes:
  *
  * NGHTTP3_ERR_INVALID_ARGUMENT
  *     The another data associated to |key| is already present.
  */
-static nghttp3_ssize map_insert(nghttp3_map *map, nghttp3_map_key_type key,
-                                void *data) {
+static int map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data) {
   size_t idx = map_index(map, key);
   size_t mask = ((size_t)1 << map->hashbits) - 1;
   size_t psl = 1;
@@ -148,16 +150,16 @@ static nghttp3_ssize map_insert(nghttp3_map *map, nghttp3_map_key_type key,
     kpsl = map->psl[idx];

     if (kpsl == 0) {
-      map_set_entry(map, idx, key, data, psl);
+      map_set_entry(map, idx, key, psl, data);
       ++map->size;

-      return (nghttp3_ssize)idx;
+      return 0;
     }

     if (psl > kpsl) {
       NGHTTP3_SWAP(nghttp3_map_key_type, &key, &map->keys[idx]);
+      NGHTTP3_SWAP(size_t, &psl, &map->psl[idx]);
       NGHTTP3_SWAP(void *, &data, &map->data[idx]);
-      NGHTTP3_SWAP(uint8_t, &psl, &map->psl[idx]);
     } else if (map->keys[idx] == key) {
       /* This check ensures that no duplicate keys are inserted.  But
          it is just a waste after first swap or if this function is
@@ -179,14 +181,14 @@ static nghttp3_ssize map_insert(nghttp3_map *map, nghttp3_map_key_type key,
 static int map_resize(nghttp3_map *map, size_t new_hashbits) {
   size_t i;
   size_t tablelen;
-  nghttp3_ssize idx;
   nghttp3_map new_map = {
     .mem = map->mem,
     .seed = map->seed,
     .hashbits = new_hashbits,
   };
   void *buf;
-  (void)idx;
+  int rv;
+  (void)rv;

   if (new_hashbits > NGHTTP3_MAP_MAX_HASHBITS) {
     return NGHTTP3_ERR_NOMEM;
@@ -195,16 +197,16 @@ static int map_resize(nghttp3_map *map, size_t new_hashbits) {
   tablelen = (size_t)1 << new_hashbits;

   buf = nghttp3_mem_calloc(map->mem, tablelen,
-                           sizeof(nghttp3_map_key_type) + sizeof(void *) +
-                             sizeof(uint8_t));
-  if (buf == NULL) {
+                           sizeof(nghttp3_map_key_type) + sizeof(size_t) +
+                             sizeof(void *));
+  if (!buf) {
     return NGHTTP3_ERR_NOMEM;
   }

   new_map.keys = buf;
-  new_map.data =
-    (void *)((uint8_t *)new_map.keys + tablelen * sizeof(nghttp3_map_key_type));
-  new_map.psl = (uint8_t *)new_map.data + tablelen * sizeof(void *);
+  new_map.psl = (size_t *)(void *)((uint8_t *)new_map.keys +
+                                   tablelen * sizeof(nghttp3_map_key_type));
+  new_map.data = (void *)((uint8_t *)new_map.psl + tablelen * sizeof(size_t));

   if (map->size) {
     tablelen = (size_t)1 << map->hashbits;
@@ -214,31 +216,26 @@ static int map_resize(nghttp3_map *map, size_t new_hashbits) {
         continue;
       }

-      idx = map_insert(&new_map, map->keys[i], map->data[i]);
+      rv = map_insert(&new_map, map->keys[i], map->data[i]);

       /* map_insert must not fail because all keys are unique during
          resize. */
-      assert(idx >= 0);
+      assert(0 == rv);
     }
   }

   nghttp3_mem_free(map->mem, map->keys);
   map->keys = new_map.keys;
-  map->data = new_map.data;
   map->psl = new_map.psl;
+  map->data = new_map.data;
   map->hashbits = new_hashbits;

   return 0;
 }

-/* NGHTTP3_MAX_PSL_RESIZE_THRESH is the maximum psl threshold.  If
-   reached, resize the table. */
-#define NGHTTP3_MAX_PSL_RESIZE_THRESH 128
-
 int nghttp3_map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data) {
   int rv;
   size_t tablelen;
-  nghttp3_ssize idx;

   assert(data);

@@ -255,27 +252,9 @@ int nghttp3_map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data) {
     if (rv != 0) {
       return rv;
     }
-
-    idx = map_insert(map, key, data);
-    if (idx < 0) {
-      return (int)idx;
-    }
-
-    return 0;
-  }
-
-  idx = map_insert(map, key, data);
-  if (idx < 0) {
-    return (int)idx;
-  }
-
-  /* Resize if psl reaches really large value which is almost
-     improbable, but just in case. */
-  if (map->psl[idx] - 1 < NGHTTP3_MAX_PSL_RESIZE_THRESH) {
-    return 0;
   }

-  return map_resize(map, map->hashbits + 1);
+  return map_insert(map, key, data);
 }

 void *nghttp3_map_find(const nghttp3_map *map, nghttp3_map_key_type key) {
@@ -333,7 +312,7 @@ int nghttp3_map_remove(nghttp3_map *map, nghttp3_map_key_type key) {
           break;
         }

-        map_set_entry(map, dest, map->keys[idx], map->data[idx], kpsl - 1);
+        map_set_entry(map, dest, map->keys[idx], kpsl - 1, map->data[idx]);

         dest = idx;

diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_map.h b/deps/ngtcp2/nghttp3/lib/nghttp3_map.h
index 337f3d63114..89867fd0546 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_map.h
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_map.h
@@ -41,11 +41,11 @@ typedef uint64_t nghttp3_map_key_type;

 typedef struct nghttp3_map {
   nghttp3_map_key_type *keys;
-  void **data;
   /* psl is the Probe Sequence Length.  0 has special meaning that the
      element is not stored at i-th position if psl[i] == 0.  Because
      of this, the actual psl value is psl[i] - 1 if psl[i] > 0. */
-  uint8_t *psl;
+  size_t *psl;
+  void **data;
   const nghttp3_mem *mem;
   uint64_t seed;
   size_t size;
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c
index 8e950a201d8..2e3d063e138 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c
@@ -2568,24 +2568,23 @@ nghttp3_ssize nghttp3_qpack_encoder_read_decoder(nghttp3_qpack_encoder *encoder,
   for (; p != end;) {
     switch (encoder->state) {
     case NGHTTP3_QPACK_DS_STATE_OPCODE:
-      switch ((*p) & 0xC0U) {
-      case 0x80U:
-      case 0xC0U:
-        DEBUGF("qpack::encode: OPCODE_SECTION_ACK\n");
-        encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_SECTION_ACK;
-        encoder->rstate.prefix = 7;
+      switch ((*p) >> 6) {
+      case 0x0U:
+        DEBUGF("qpack::encode: OPCODE_ICNT_INCREMENT\n");
+        encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_ICNT_INCREMENT;
+        encoder->rstate.prefix = 6;

         break;
-      case 0x40U:
+      case 0x1U:
         DEBUGF("qpack::encode: OPCODE_STREAM_CANCEL\n");
         encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_STREAM_CANCEL;
         encoder->rstate.prefix = 6;

         break;
       default:
-        DEBUGF("qpack::encode: OPCODE_ICNT_INCREMENT\n");
-        encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_ICNT_INCREMENT;
-        encoder->rstate.prefix = 6;
+        DEBUGF("qpack::encode: OPCODE_SECTION_ACK\n");
+        encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_SECTION_ACK;
+        encoder->rstate.prefix = 7;
       }
       encoder->state = NGHTTP3_QPACK_DS_STATE_READ_NUMBER;
       /* fall through */
@@ -2842,39 +2841,36 @@ nghttp3_ssize nghttp3_qpack_decoder_read_encoder(nghttp3_qpack_decoder *decoder,
     busy = 0;
     switch (decoder->state) {
     case NGHTTP3_QPACK_ES_STATE_OPCODE:
-      switch ((*p) & 0xE0U) {
-      case 0x80U:
-      case 0xA0U:
-      case 0xC0U:
-      case 0xE0U:
-        DEBUGF("qpack::decode: OPCODE_INSERT_INDEXED\n");
-        decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_INSERT_INDEXED;
-        decoder->rstate.dynamic = !((*p) & 0x40U);
-        decoder->rstate.prefix = 6;
+      switch ((*p) >> 5) {
+      case 0x0U:
+        DEBUGF("qpack::decode: OPCODE_DUPLICATE\n");
+        decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_DUPLICATE;
+        decoder->rstate.dynamic = 1;
+        decoder->rstate.prefix = 5;
         decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;

         break;
-      case 0x40U:
-      case 0x60U:
+      case 0x1U:
+        DEBUGF("qpack::decode: OPCODE_SET_DTABLE_TABLE_CAP\n");
+        decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_SET_DTABLE_CAP;
+        decoder->rstate.prefix = 5;
+        decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;
+
+        break;
+      case 0x2U:
+      case 0x3U:
         DEBUGF("qpack::decode: OPCODE_INSERT\n");
         decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_INSERT;
         decoder->rstate.dynamic = 0;
         decoder->rstate.prefix = 5;
         decoder->state = NGHTTP3_QPACK_ES_STATE_CHECK_NAME_HUFFMAN;

-        break;
-      case 0x20U:
-        DEBUGF("qpack::decode: OPCODE_SET_DTABLE_TABLE_CAP\n");
-        decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_SET_DTABLE_CAP;
-        decoder->rstate.prefix = 5;
-        decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;
-
         break;
       default:
-        DEBUGF("qpack::decode: OPCODE_DUPLICATE\n");
-        decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_DUPLICATE;
-        decoder->rstate.dynamic = 1;
-        decoder->rstate.prefix = 5;
+        DEBUGF("qpack::decode: OPCODE_INSERT_INDEXED\n");
+        decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_INSERT_INDEXED;
+        decoder->rstate.dynamic = !((*p) & 0x40U);
+        decoder->rstate.prefix = 6;
         decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;
       }
       break;
@@ -2895,6 +2891,12 @@ nghttp3_ssize nghttp3_qpack_decoder_read_encoder(nghttp3_qpack_decoder *decoder,
       if (decoder->opcode == NGHTTP3_QPACK_ES_OPCODE_SET_DTABLE_CAP) {
         DEBUGF("qpack::decode: Set dtable capacity to %" PRIu64 "\n",
                decoder->rstate.left);
+#if SIZE_MAX < UINT64_MAX
+        if (decoder->rstate.left > SIZE_MAX) {
+          return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
+        }
+#endif /* SIZE_MAX < UINT64_MAX */
+
         rv = nghttp3_qpack_decoder_set_max_dtable_capacity(
           decoder, (size_t)decoder->rstate.left);
         if (rv != 0) {
@@ -3433,36 +3435,26 @@ nghttp3_qpack_decoder_read_request(nghttp3_qpack_decoder *decoder,
     case NGHTTP3_QPACK_RS_STATE_OPCODE:
       assert(sctx->rstate.left == 0);
       assert(sctx->rstate.shift == 0);
-      switch ((*p) & 0xF0U) {
-      case 0x80U:
-      case 0x90U:
-      case 0xA0U:
-      case 0xB0U:
-      case 0xC0U:
-      case 0xD0U:
-      case 0xE0U:
-      case 0xF0U:
-        DEBUGF("qpack::decode: OPCODE_INDEXED\n");
-        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED;
-        sctx->rstate.dynamic = !((*p) & 0x40U);
-        sctx->rstate.prefix = 6;
+      switch ((*p) >> 4) {
+      case 0x0U:
+        DEBUGF("qpack::decode: OPCODE_INDEXED_NAME_PB\n");
+        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME_PB;
+        sctx->rstate.never = (*p) & 0x08U;
+        sctx->rstate.dynamic = 1;
+        sctx->rstate.prefix = 3;
         sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;

         break;
-      case 0x40U:
-      case 0x50U:
-      case 0x60U:
-      case 0x70U:
-        DEBUGF("qpack::decode: OPCODE_INDEXED_NAME\n");
-        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME;
-        sctx->rstate.never = (*p) & 0x20U;
-        sctx->rstate.dynamic = !((*p) & 0x10U);
+      case 0x1U:
+        DEBUGF("qpack::decode: OPCODE_INDEXED_PB\n");
+        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_PB;
+        sctx->rstate.dynamic = 1;
         sctx->rstate.prefix = 4;
         sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;

         break;
-      case 0x20U:
-      case 0x30U:
+      case 0x2U:
+      case 0x3U:
         DEBUGF("qpack::decode: OPCODE_LITERAL\n");
         sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_LITERAL;
         sctx->rstate.never = (*p) & 0x10U;
@@ -3471,20 +3463,23 @@ nghttp3_qpack_decoder_read_request(nghttp3_qpack_decoder *decoder,
         sctx->state = NGHTTP3_QPACK_RS_STATE_CHECK_NAME_HUFFMAN;

         break;
-      case 0x10U:
-        DEBUGF("qpack::decode: OPCODE_INDEXED_PB\n");
-        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_PB;
-        sctx->rstate.dynamic = 1;
+      case 0x4U:
+      case 0x5U:
+      case 0x6U:
+      case 0x7U:
+        DEBUGF("qpack::decode: OPCODE_INDEXED_NAME\n");
+        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME;
+        sctx->rstate.never = (*p) & 0x20U;
+        sctx->rstate.dynamic = !((*p) & 0x10U);
         sctx->rstate.prefix = 4;
         sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;

         break;
       default:
-        DEBUGF("qpack::decode: OPCODE_INDEXED_NAME_PB\n");
-        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME_PB;
-        sctx->rstate.never = (*p) & 0x08U;
-        sctx->rstate.dynamic = 1;
-        sctx->rstate.prefix = 3;
+        DEBUGF("qpack::decode: OPCODE_INDEXED\n");
+        sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED;
+        sctx->rstate.dynamic = !((*p) & 0x40U);
+        sctx->rstate.prefix = 6;
         sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;
       }
       break;
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.c b/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.c
index d7a0267530c..d6d0738e5de 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.c
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.c
@@ -32,6 +32,8 @@

 void nghttp3_ratelim_init(nghttp3_ratelim *rlim, uint64_t burst, uint64_t rate,
                           nghttp3_tstamp ts) {
+  burst = nghttp3_min(burst, NGHTTP3_RATELIM_MAX_BURST);
+
   *rlim = (nghttp3_ratelim){
     .burst = burst,
     .rate = rate,
@@ -53,19 +55,16 @@ static void ratelim_update(nghttp3_ratelim *rlim, nghttp3_tstamp ts) {
   d = ts - rlim->ts;
   rlim->ts = ts;

-  if (rlim->rate > (UINT64_MAX - rlim->carry) / d) {
-    gain = UINT64_MAX;
-  } else {
+  if (rlim->rate <= (UINT64_MAX - rlim->carry) / d) {
     gain = rlim->rate * d + rlim->carry;
-  }
+    gps = gain / NGHTTP3_SECONDS;

-  gps = gain / NGHTTP3_SECONDS;
+    if (gps < rlim->burst && rlim->tokens < rlim->burst - gps) {
+      rlim->tokens += gps;
+      rlim->carry = gain % NGHTTP3_SECONDS;

-  if (gps < rlim->burst && rlim->tokens < rlim->burst - gps) {
-    rlim->tokens += gps;
-    rlim->carry = gain % NGHTTP3_SECONDS;
-
-    return;
+      return;
+    }
   }

   rlim->tokens = rlim->burst;
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.h b/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.h
index 68aab93a61b..ba8f5378814 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.h
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_ratelim.h
@@ -33,6 +33,9 @@

 #include <nghttp3/nghttp3.h>

+/* NGHTTP3_RATELIM_MAX_BURST is the maximum value of the burst. */
+#define NGHTTP3_RATELIM_MAX_BURST (UINT64_MAX / NGHTTP3_SECONDS)
+
 typedef struct nghttp3_ratelim {
   /* burst is the maximum number of tokens. */
   uint64_t burst;
@@ -48,8 +51,8 @@ typedef struct nghttp3_ratelim {
   nghttp3_tstamp ts;
 } nghttp3_ratelim;

-/* nghttp3_ratelim_init initializes |rlim| with the given
-   parameters. */
+/* nghttp3_ratelim_init initializes |rlim| with the given parameters.
+   |burst| is clamped to NGHTTP3_RATELIM_MAX_BURST. */
 void nghttp3_ratelim_init(nghttp3_ratelim *rlim, uint64_t burst, uint64_t rate,
                           nghttp3_tstamp ts);

diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h
index d313b1c192b..07d71573a58 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_stream.h
@@ -42,8 +42,9 @@
 #define NGHTTP3_STREAM_MIN_CHUNK_SIZE 256

 /* NGHTTP3_MIN_UNSENT_BYTES is the minimum unsent bytes which is large
-   enough to fill outgoing single QUIC packet. */
-#define NGHTTP3_MIN_UNSENT_BYTES 4096
+   enough to fill outgoing single QUIC packet or TLS record in case of
+   QMux (Cut 2 bytes for QMux record length). */
+#define NGHTTP3_MIN_UNSENT_BYTES 16382

 /* NGHTTP3_STREAM_MIN_WRITELEN is the minimum length of write to cause
    the stream to reschedule. */
diff --git a/deps/ngtcp2/nghttp3/lib/nghttp3_unreachable.h b/deps/ngtcp2/nghttp3/lib/nghttp3_unreachable.h
index c609d7ed72f..362ceb08c3d 100644
--- a/deps/ngtcp2/nghttp3/lib/nghttp3_unreachable.h
+++ b/deps/ngtcp2/nghttp3/lib/nghttp3_unreachable.h
@@ -44,10 +44,10 @@
 #ifdef _MSC_VER
 __declspec(noreturn)
 #endif /* defined(_MSC_VER) */
-    void nghttp3_unreachable_fail(const char *file, int line, const char *func)
+void nghttp3_unreachable_fail(const char *file, int line, const char *func)
 #ifndef _MSC_VER
-        __attribute__((noreturn))
+  __attribute__((noreturn))
 #endif /* !defined(_MSC_VER) */
-        ;
+  ;

 #endif /* !defined(NGHTTP3_UNREACHABLE_H) */