diff --git a/NEWS b/NEWS
index a0bce4ed6f43..b129a166df34 100644
--- a/NEWS
+++ b/NEWS
@@ -57,6 +57,8 @@ PHP NEWS
after a dot segment in a path, replacement file drive paths, the output
encoding used for percent-encoding, the URLSearchParams tail pointer and
fragment serialization without a query. (alexandre-daubois)
+ . Merge patch lexbor/lexbor@f4cbbcd, fixing lexbor_array_obj_t allocating 8
+ times the memory it uses. (Nicolas Grekas)
- LibXML:
. Clear the libxml last error in libxml_use_internal_errors(false).
diff --git a/ext/dom/tests/gh25118.phpt b/ext/dom/tests/gh25118.phpt
index 790ae71ef337..a8bc65bb22bb 100644
--- a/ext/dom/tests/gh25118.phpt
+++ b/ext/dom/tests/gh25118.phpt
@@ -5,13 +5,14 @@ dom
--SKIPIF--
--INI--
-memory_limit=32M
+memory_limit=26M
--FILE--
t
n' . str_repeat('', 100000) . '';
Dom\HTMLDocument::createFromString($html, LIBXML_NOERROR);
?>
--EXPECTF--
-Fatal error: Allowed memory size of 33554432 bytes exhausted %S(tried to allocate %d bytes) in %s on line %d
+Fatal error: Allowed memory size of 27262976 bytes exhausted %S(tried to allocate %d bytes) in %s on line %d
diff --git a/ext/lexbor/lexbor/core/array_obj.c b/ext/lexbor/lexbor/core/array_obj.c
index 79a4c3a65a81..8cceaf9fe018 100644
--- a/ext/lexbor/lexbor/core/array_obj.c
+++ b/ext/lexbor/lexbor/core/array_obj.c
@@ -29,8 +29,7 @@ lexbor_array_obj_init(lexbor_array_obj_t *array,
array->size = size;
array->struct_size = struct_size;
- array->list = lexbor_malloc(sizeof(uint8_t *)
- * (array->size * struct_size));
+ array->list = lexbor_malloc(array->size * struct_size);
if (array->list == NULL) {
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
}
@@ -77,8 +76,7 @@ lexbor_array_obj_expand(lexbor_array_obj_t *array, size_t up_to)
new_size = array->length + up_to;
- list = lexbor_realloc(array->list, sizeof(uint8_t *)
- * (new_size * array->struct_size));
+ list = lexbor_realloc(array->list, new_size * array->struct_size);
if (list == NULL) {
return NULL;
}
@@ -170,8 +168,7 @@ lexbor_array_obj_delete(lexbor_array_obj_t *array, size_t begin, size_t length)
memmove(&array->list[ begin * array->struct_size ],
&array->list[ end_len * array->struct_size ],
- sizeof(uint8_t *)
- * ((array->length - end_len) * array->struct_size));
+ (array->length - end_len) * array->struct_size);
array->length -= length;
}
diff --git a/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch b/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch
index 2cd28f9eaf1d..3a4a2072682a 100644
--- a/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch
+++ b/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Sat, 26 Aug 2023 15:08:59 +0200
-Subject: [PATCH 01/24] Expose line and column information for use in PHP
+Subject: [PATCH 01/25] Expose line and column information for use in PHP
---
source/lexbor/dom/interfaces/node.h | 2 ++
diff --git a/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch b/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch
index 4cff1b906f8d..6cfa2fe40607 100644
--- a/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch
+++ b/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Mon, 14 Aug 2023 20:18:51 +0200
-Subject: [PATCH 02/24] Track implied added nodes for options use in PHP
+Subject: [PATCH 02/25] Track implied added nodes for options use in PHP
---
source/lexbor/html/tree.h | 3 +++
diff --git a/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch b/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch
index 19b411b2ffcf..df0778c5c8ca 100644
--- a/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch
+++ b/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Thu, 24 Aug 2023 22:57:48 +0200
-Subject: [PATCH 03/24] Patch utilities and data structure to be able to
+Subject: [PATCH 03/25] Patch utilities and data structure to be able to
generate smaller lookup tables
Changed the generation script to check if everything fits in 32-bits.
diff --git a/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch b/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch
index 67f241a96cf9..aab66f18babc 100644
--- a/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch
+++ b/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Wed, 29 Nov 2023 21:26:47 +0100
-Subject: [PATCH 04/24] Remove unused upper case tag static data
+Subject: [PATCH 04/25] Remove unused upper case tag static data
---
source/lexbor/tag/res.h | 2 ++
diff --git a/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch b/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch
index a36832333e12..441e3f5d155e 100644
--- a/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch
+++ b/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Wed, 29 Nov 2023 21:29:31 +0100
-Subject: [PATCH 05/24] Shrink size of static binary search tree
+Subject: [PATCH 05/25] Shrink size of static binary search tree
This also makes it more efficient on the data cache.
---
diff --git a/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch b/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch
index fa25a94ef3fa..b9466577c059 100644
--- a/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch
+++ b/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Sun, 7 Jan 2024 21:59:28 +0100
-Subject: [PATCH 06/24] Patch out unused CSS style code
+Subject: [PATCH 06/25] Patch out unused CSS style code
---
source/lexbor/css/rule.h | 2 ++
diff --git a/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch b/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch
index 2f939cb69f2c..22ab3caea1f7 100644
--- a/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch
+++ b/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?=
Date: Sun, 17 May 2026 22:17:14 +0200
-Subject: [PATCH 07/24] Add lxb_url_is_special() to the public API (#362)
+Subject: [PATCH 07/25] Add lxb_url_is_special() to the public API (#362)
As https://wiki.php.net/rfc/uri_followup#uri_type_detection relies on this information.
---
diff --git a/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch b/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch
index d72c82fbdaea..6ffd2f11f1cb 100644
--- a/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch
+++ b/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Fri, 26 Jun 2026 18:55:56 +0300
-Subject: [PATCH 08/24] URL: fixed setters for empty hosts.
+Subject: [PATCH 08/25] URL: fixed setters for empty hosts.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
diff --git a/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch b/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch
index b2ac318e2ec6..8a6c4a9d2f4f 100644
--- a/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch
+++ b/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Fri, 5 Jun 2026 22:13:32 +0300
-Subject: [PATCH 09/24] URL: fixed uninitialized memory in the path buffer
+Subject: [PATCH 09/25] URL: fixed uninitialized memory in the path buffer
growth.
When a path was long enough to outgrow the on-stack buffer, the first
diff --git a/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch b/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch
index 937722a246b5..8f3ed0c5b05a 100644
--- a/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch
+++ b/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?=
Date: Thu, 9 Jul 2026 21:51:05 +0200
-Subject: [PATCH 10/24] Fix parsing for URL containing empty host and userinfo
+Subject: [PATCH 10/25] Fix parsing for URL containing empty host and userinfo
The returned error code (LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS) apparently contradicts the specification:
diff --git a/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch b/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch
index 9c1a0708a756..542488d1049f 100644
--- a/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch
+++ b/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?=
Date: Fri, 10 Jul 2026 22:31:16 +0200
-Subject: [PATCH 11/24] Percent-encode the caret in the path
+Subject: [PATCH 11/25] Percent-encode the caret in the path
The caret (^) is part of the path percent-encode set:
diff --git a/ext/lexbor/patches/0012-URL-added-public-IPv6-parser.patch b/ext/lexbor/patches/0012-URL-added-public-IPv6-parser.patch
index a4007d2a68f9..d4dccb9b898f 100644
--- a/ext/lexbor/patches/0012-URL-added-public-IPv6-parser.patch
+++ b/ext/lexbor/patches/0012-URL-added-public-IPv6-parser.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Wed, 12 Aug 2026 23:29:20 +0300
-Subject: [PATCH 12/24] URL: added public IPv6 parser.
+Subject: [PATCH 12/25] URL: added public IPv6 parser.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
diff --git a/ext/lexbor/patches/0013-URL-added-public-percent-encoder-API.patch b/ext/lexbor/patches/0013-URL-added-public-percent-encoder-API.patch
index 729969019b40..9f44f2cce2f1 100644
--- a/ext/lexbor/patches/0013-URL-added-public-percent-encoder-API.patch
+++ b/ext/lexbor/patches/0013-URL-added-public-percent-encoder-API.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Thu, 13 Aug 2026 23:29:16 +0300
-Subject: [PATCH 13/24] URL: added public percent-encoder API.
+Subject: [PATCH 13/25] URL: added public percent-encoder API.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
diff --git a/ext/lexbor/patches/0014-CSS-fixed-heap-buffer-overflow-in-lexbor-contains-pa.patch b/ext/lexbor/patches/0014-CSS-fixed-heap-buffer-overflow-in-lexbor-contains-pa.patch
index 373a579e0842..f6fa34ec0609 100644
--- a/ext/lexbor/patches/0014-CSS-fixed-heap-buffer-overflow-in-lexbor-contains-pa.patch
+++ b/ext/lexbor/patches/0014-CSS-fixed-heap-buffer-overflow-in-lexbor-contains-pa.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Fri, 5 Jun 2026 22:34:23 +0300
-Subject: [PATCH 14/24] CSS: fixed heap buffer overflow in :lexbor-contains()
+Subject: [PATCH 14/25] CSS: fixed heap buffer overflow in :lexbor-contains()
parsing.
The contains string buffer was allocated by the size of the string
diff --git a/ext/lexbor/patches/0015-Encoding-fixed-buffer-overflows-in-malformed-decode-.patch b/ext/lexbor/patches/0015-Encoding-fixed-buffer-overflows-in-malformed-decode-.patch
index 68756c46547e..3d2abe02550a 100644
--- a/ext/lexbor/patches/0015-Encoding-fixed-buffer-overflows-in-malformed-decode-.patch
+++ b/ext/lexbor/patches/0015-Encoding-fixed-buffer-overflows-in-malformed-decode-.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Wed, 10 Jun 2026 19:50:10 +0300
-Subject: [PATCH 15/24] Encoding: fixed buffer overflows in malformed decode
+Subject: [PATCH 15/25] Encoding: fixed buffer overflows in malformed decode
replay.
Fixed out-of-bounds writes in buffering decoders when replacement output
diff --git a/ext/lexbor/patches/0016-URL-fixed-tail-pointer-in-URLSearchParams-for-delimi.patch b/ext/lexbor/patches/0016-URL-fixed-tail-pointer-in-URLSearchParams-for-delimi.patch
index bc44d2ec9b43..f8e9a9bf1ff2 100644
--- a/ext/lexbor/patches/0016-URL-fixed-tail-pointer-in-URLSearchParams-for-delimi.patch
+++ b/ext/lexbor/patches/0016-URL-fixed-tail-pointer-in-URLSearchParams-for-delimi.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Fri, 5 Jun 2026 21:46:26 +0300
-Subject: [PATCH 16/24] URL: fixed tail pointer in URLSearchParams for
+Subject: [PATCH 16/25] URL: fixed tail pointer in URLSearchParams for
delimiter-free query.
When a query had a single token without '=' or '&' (e.g. "?abc"), the
diff --git a/ext/lexbor/patches/0017-URL-Fix-parsing-of-usernames-containing.patch b/ext/lexbor/patches/0017-URL-Fix-parsing-of-usernames-containing.patch
index f6009b9709fa..d5719b2abad9 100644
--- a/ext/lexbor/patches/0017-URL-Fix-parsing-of-usernames-containing.patch
+++ b/ext/lexbor/patches/0017-URL-Fix-parsing-of-usernames-containing.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20D=C3=BCsterhus?=
Date: Fri, 31 Jul 2026 20:56:18 +0200
-Subject: [PATCH 17/24] URL: Fix parsing of usernames containing `@`
+Subject: [PATCH 17/25] URL: Fix parsing of usernames containing `@`
Fixes lexbor/lexbor#399.
---
diff --git a/ext/lexbor/patches/0018-Unicode-fixed-uninitialized-memory-in-IDNA-buffer-gr.patch b/ext/lexbor/patches/0018-Unicode-fixed-uninitialized-memory-in-IDNA-buffer-gr.patch
index 23c4cf1acc03..34029e75d97f 100644
--- a/ext/lexbor/patches/0018-Unicode-fixed-uninitialized-memory-in-IDNA-buffer-gr.patch
+++ b/ext/lexbor/patches/0018-Unicode-fixed-uninitialized-memory-in-IDNA-buffer-gr.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Mon, 7 Sep 2026 22:11:39 +0300
-Subject: [PATCH 18/24] Unicode: fixed uninitialized memory in IDNA buffer
+Subject: [PATCH 18/25] Unicode: fixed uninitialized memory in IDNA buffer
growth.
When an IDNA buffer outgrew the stack allocation, the move to the heap
diff --git a/ext/lexbor/patches/0019-URL-encode-opaque-path-spaces-before-query-and-fragm.patch b/ext/lexbor/patches/0019-URL-encode-opaque-path-spaces-before-query-and-fragm.patch
index 4d8338521997..8ee829a14b70 100644
--- a/ext/lexbor/patches/0019-URL-encode-opaque-path-spaces-before-query-and-fragm.patch
+++ b/ext/lexbor/patches/0019-URL-encode-opaque-path-spaces-before-query-and-fragm.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?=
Date: Fri, 11 Sep 2026 21:58:45 +0200
-Subject: [PATCH 19/24] URL: encode opaque path spaces before query and
+Subject: [PATCH 19/25] URL: encode opaque path spaces before query and
fragment. (#405)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
diff --git a/ext/lexbor/patches/0020-URL-Fix-lxb_url_serialize_fragment-without-a-query-4.patch b/ext/lexbor/patches/0020-URL-Fix-lxb_url_serialize_fragment-without-a-query-4.patch
index a0eecf7234be..07f44d7a3fe8 100644
--- a/ext/lexbor/patches/0020-URL-Fix-lxb_url_serialize_fragment-without-a-query-4.patch
+++ b/ext/lexbor/patches/0020-URL-Fix-lxb_url_serialize_fragment-without-a-query-4.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20D=C3=BCsterhus?=
Date: Fri, 11 Sep 2026 22:45:33 +0200
-Subject: [PATCH 20/24] URL: Fix `lxb_url_serialize_fragment()` without a query
+Subject: [PATCH 20/25] URL: Fix `lxb_url_serialize_fragment()` without a query
(#410)
The `lxb_url_serialize_fragment()` function checked if the query contained data
diff --git a/ext/lexbor/patches/0021-URL-expose-component-reset-functions.-415.patch b/ext/lexbor/patches/0021-URL-expose-component-reset-functions.-415.patch
index deaac125e82e..caed16aba8be 100644
--- a/ext/lexbor/patches/0021-URL-expose-component-reset-functions.-415.patch
+++ b/ext/lexbor/patches/0021-URL-expose-component-reset-functions.-415.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?=
Date: Tue, 22 Sep 2026 22:20:28 +0200
-Subject: [PATCH 21/24] URL: expose component reset functions. (#415)
+Subject: [PATCH 21/25] URL: expose component reset functions. (#415)
* URL: expose component reset functions.
diff --git a/ext/lexbor/patches/0022-URL-Fix-parsing-of-query-and-fragment-after-a-dot-co.patch b/ext/lexbor/patches/0022-URL-Fix-parsing-of-query-and-fragment-after-a-dot-co.patch
index 4f9607068b9d..62b5607e7092 100644
--- a/ext/lexbor/patches/0022-URL-Fix-parsing-of-query-and-fragment-after-a-dot-co.patch
+++ b/ext/lexbor/patches/0022-URL-Fix-parsing-of-query-and-fragment-after-a-dot-co.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20D=C3=BCsterhus?=
Date: Sat, 26 Sep 2026 18:41:05 +0200
-Subject: [PATCH 22/24] URL: Fix parsing of query and fragment after a
+Subject: [PATCH 22/25] URL: Fix parsing of query and fragment after a
dot-component in path (#411)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
diff --git a/ext/lexbor/patches/0023-URL-Keep-replacement-file-drive-paths-hierarchical-4.patch b/ext/lexbor/patches/0023-URL-Keep-replacement-file-drive-paths-hierarchical-4.patch
index 2caee494342d..e8562311f164 100644
--- a/ext/lexbor/patches/0023-URL-Keep-replacement-file-drive-paths-hierarchical-4.patch
+++ b/ext/lexbor/patches/0023-URL-Keep-replacement-file-drive-paths-hierarchical-4.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?=
Date: Mon, 21 Sep 2026 20:01:43 +0200
-Subject: [PATCH 23/24] URL: Keep replacement file drive paths hierarchical
+Subject: [PATCH 23/25] URL: Keep replacement file drive paths hierarchical
(#423)
WHATWG file state (https://url.spec.whatwg.org/#file-state) step 4.4.3.2 resets the path to an empty list. Do not mark it opaque, as that makes subsequent pathname updates silently do nothing.
diff --git a/ext/lexbor/patches/0024-URL-normalize-output-encoding-for-percent-encoding.patch b/ext/lexbor/patches/0024-URL-normalize-output-encoding-for-percent-encoding.patch
index c0d192d24eaf..3f18aada984b 100644
--- a/ext/lexbor/patches/0024-URL-normalize-output-encoding-for-percent-encoding.patch
+++ b/ext/lexbor/patches/0024-URL-normalize-output-encoding-for-percent-encoding.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Borisov
Date: Thu, 24 Sep 2026 15:05:51 +0300
-Subject: [PATCH 24/24] URL: normalize output encoding for percent-encoding.
+Subject: [PATCH 24/25] URL: normalize output encoding for percent-encoding.
---
source/lexbor/url/url.c | 34 +++++++++++++++++++++++++---------
diff --git a/ext/lexbor/patches/0025-Core-fixed-allocation-and-move-sizes-in-lexbor_array.patch b/ext/lexbor/patches/0025-Core-fixed-allocation-and-move-sizes-in-lexbor_array.patch
new file mode 100644
index 000000000000..5744a1eb9fac
--- /dev/null
+++ b/ext/lexbor/patches/0025-Core-fixed-allocation-and-move-sizes-in-lexbor_array.patch
@@ -0,0 +1,52 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Nicolas Grekas
+Date: Mon, 28 Sep 2026 21:25:27 +0200
+Subject: [PATCH 25/25] Core: fixed allocation and move sizes in
+ lexbor_array_obj_t. (#428)
+
+lexbor_array_obj_init() and lexbor_array_obj_expand() multiplied the
+number of bytes they need by sizeof(uint8_t *), so they allocated 8
+times too much memory on 64-bit platforms. lexbor_array_obj_delete()
+moved 8 times the bytes of the remaining entries too, which only stayed
+within bounds thanks to the oversized allocation.
+
+Added tests for the allocated sizes and for the entries after the last
+one being left untouched by lexbor_array_obj_delete().
+---
+ source/lexbor/core/array_obj.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/source/lexbor/core/array_obj.c b/source/lexbor/core/array_obj.c
+index 79a4c3a..8cceaf9 100644
+--- a/source/lexbor/core/array_obj.c
++++ b/source/lexbor/core/array_obj.c
+@@ -29,8 +29,7 @@ lexbor_array_obj_init(lexbor_array_obj_t *array,
+ array->size = size;
+ array->struct_size = struct_size;
+
+- array->list = lexbor_malloc(sizeof(uint8_t *)
+- * (array->size * struct_size));
++ array->list = lexbor_malloc(array->size * struct_size);
+ if (array->list == NULL) {
+ return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
+ }
+@@ -77,8 +76,7 @@ lexbor_array_obj_expand(lexbor_array_obj_t *array, size_t up_to)
+
+ new_size = array->length + up_to;
+
+- list = lexbor_realloc(array->list, sizeof(uint8_t *)
+- * (new_size * array->struct_size));
++ list = lexbor_realloc(array->list, new_size * array->struct_size);
+ if (list == NULL) {
+ return NULL;
+ }
+@@ -170,8 +168,7 @@ lexbor_array_obj_delete(lexbor_array_obj_t *array, size_t begin, size_t length)
+
+ memmove(&array->list[ begin * array->struct_size ],
+ &array->list[ end_len * array->struct_size ],
+- sizeof(uint8_t *)
+- * ((array->length - end_len) * array->struct_size));
++ (array->length - end_len) * array->struct_size);
+
+ array->length -= length;
+ }