Skip to content

Commit d18b498

Browse files
lexbor: Merge upstream WHATWG URL and memory safety fixes
1 parent 7a4c627 commit d18b498

23 files changed

Lines changed: 415 additions & 36 deletions

NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ PHP NEWS
1111
registrations are freed while still reachable from the cycle collector.
1212
(Ilia Alshanetsky)
1313

14+
- Lexbor:
15+
. Merge patches 859f100, 8a14bc0, f67ce4b, a36e09a and b0f7412, fixing a heap
16+
buffer overflow in :lexbor-contains() parsing, buffer overflows in malformed
17+
decode replay, uninitialized memory in IDNA buffer growth, dropped usernames
18+
containing an at sign and the URLSearchParams tail pointer.
19+
(alexandre-daubois)
20+
1421

1522
24 Sep 2026, PHP 8.5.11
1623

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
CSS Selectors - Pseudo classes: :lexbor-contains() with an argument longer than its string header
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$dom = Dom\HTMLDocument::createFromString('<p>needle</p>', LIBXML_NOERROR);
9+
10+
var_dump($dom->querySelectorAll(':lexbor-contains("' . str_repeat('needle', 1024) . '")')->length);
11+
var_dump($dom->querySelectorAll(':lexbor-contains("needle")')->length);
12+
13+
?>
14+
--EXPECT--
15+
int(0)
16+
int(0)

ext/lexbor/lexbor/css/selectors/pseudo_state.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,12 @@ lxb_css_selectors_state_pseudo_class_function_lexbor_contains(lxb_css_parser_t *
227227
contains->insensitive = false;
228228
str = &contains->str;
229229

230-
str->data = lexbor_mraw_alloc(parser->memory->mraw,
231-
sizeof(lexbor_str_t));
230+
str->data = lexbor_mraw_alloc(parser->memory->mraw, length + 1);
232231
if (str->data == NULL) {
233232
return lxb_css_parser_memory_fail(parser);
234233
}
235234

236-
memcpy(str->data, data, length + 1);
235+
memcpy(str->data, data, length);
237236

238237
str->length = length;
239238
str->data[length] = '\0';

ext/lexbor/lexbor/encoding/decode.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,13 @@ lxb_encoding_decode_iso_2022_jp(lxb_encoding_decode_t *ctx,
912912
}
913913
LXB_ENCODING_DECODE_ERROR_END();
914914

915+
if (ctx->buffer_used >= ctx->buffer_length) {
916+
iso->prepand = iso->lead;
917+
iso->lead = 0x00;
918+
919+
return LXB_STATUS_SMALL_BUFFER;
920+
}
921+
915922
byte = iso->lead;
916923
iso->lead = 0x00;
917924

@@ -1279,6 +1286,12 @@ lxb_encoding_decode_utf_16(lxb_encoding_decode_t *ctx, bool is_be,
12791286
}
12801287
LXB_ENCODING_DECODE_ERROR_END();
12811288

1289+
if (ctx->buffer_used >= ctx->buffer_length) {
1290+
ctx->u.lead = lead + 0x01;
1291+
1292+
return LXB_STATUS_SMALL_BUFFER;
1293+
}
1294+
12821295
goto lead_state;
12831296
}
12841297

@@ -1723,6 +1736,13 @@ lxb_encoding_decode_gb18030(lxb_encoding_decode_t *ctx,
17231736
}
17241737
LXB_ENCODING_DECODE_ERROR_END();
17251738

1739+
if (ctx->buffer_used >= ctx->buffer_length) {
1740+
ctx->prepend = true;
1741+
ctx->u.gb18030.first = second;
1742+
1743+
return LXB_STATUS_SMALL_BUFFER;
1744+
}
1745+
17261746
first = second;
17271747

17281748
goto prepend_first;
@@ -1756,11 +1776,8 @@ lxb_encoding_decode_gb18030(lxb_encoding_decode_t *ctx,
17561776
}
17571777
LXB_ENCODING_DECODE_ERROR_END();
17581778

1759-
LXB_ENCODING_DECODE_APPEND_WO_CHECK(ctx, second);
1760-
1761-
if (ctx->buffer_used == ctx->buffer_length) {
1779+
if (ctx->buffer_used >= ctx->buffer_length) {
17621780
ctx->prepend = true;
1763-
ctx->have_error = true;
17641781

17651782
/* First is a fake for trigger */
17661783
ctx->u.gb18030.first = 0x01;
@@ -1770,6 +1787,18 @@ lxb_encoding_decode_gb18030(lxb_encoding_decode_t *ctx,
17701787
return LXB_STATUS_SMALL_BUFFER;
17711788
}
17721789

1790+
LXB_ENCODING_DECODE_APPEND_WO_CHECK(ctx, second);
1791+
1792+
if (ctx->buffer_used >= ctx->buffer_length) {
1793+
ctx->prepend = true;
1794+
1795+
ctx->u.gb18030.first = third;
1796+
ctx->u.gb18030.second = 0x00;
1797+
ctx->u.gb18030.third = 0x00;
1798+
1799+
return LXB_STATUS_SMALL_BUFFER;
1800+
}
1801+
17731802
first = third;
17741803

17751804
goto prepend_first;

ext/lexbor/lexbor/unicode/idna.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,14 @@ lxb_unicode_idna_realloc(lxb_codepoint_t *buf, const lxb_codepoint_t *buffer,
117117
lxb_codepoint_t *tmp;
118118

119119
nlen = ((*buf_end - buf) * 4) + len;
120-
120+
121121
if (buf == buffer) {
122122
tmp = lexbor_malloc(nlen * sizeof(lxb_codepoint_t));
123123
if (tmp == NULL) {
124124
return NULL;
125125
}
126+
127+
memcpy(tmp, buf, (*buf_p - buf) * sizeof(lxb_codepoint_t));
126128
}
127129
else {
128130
tmp = lexbor_realloc(buf, nlen * sizeof(lxb_codepoint_t));
@@ -458,13 +460,17 @@ lxb_unicode_idna_ascii_puny_cb(const lxb_char_t *data, size_t length, void *ctx,
458460

459461
if (asc->buf == asc->buffer) {
460462
tmp = lexbor_malloc(nlen);
463+
if (tmp == NULL) {
464+
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
465+
}
466+
467+
memcpy(tmp, asc->buf, asc->p - asc->buf);
461468
}
462469
else {
463470
tmp = lexbor_realloc(asc->buf, nlen);
464-
}
465-
466-
if (tmp == NULL) {
467-
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
471+
if (tmp == NULL) {
472+
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
473+
}
468474
}
469475

470476
asc->p = tmp + (asc->p - asc->buf);
@@ -711,13 +717,17 @@ lxb_unicode_idna_to_unicode_cb(const lxb_codepoint_t *part, size_t len,
711717

712718
if (asc->buf == asc->buffer) {
713719
tmp = lexbor_malloc(nlen);
720+
if (tmp == NULL) {
721+
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
722+
}
723+
724+
memcpy(tmp, asc->buf, asc->p - asc->buf);
714725
}
715726
else {
716727
tmp = lexbor_realloc(asc->buf, nlen);
717-
}
718-
719-
if (tmp == NULL) {
720-
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
728+
if (tmp == NULL) {
729+
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
730+
}
721731
}
722732

723733
asc->p = tmp + (asc->p - asc->buf);

ext/lexbor/lexbor/url/url.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,16 +1753,13 @@ lxb_url_parse_basic_h(lxb_url_parser_t *parser, lxb_url_t *url,
17531753
break;
17541754
}
17551755

1756-
if (pswd == NULL || !at_sign) {
1757-
tmp = (pswd != NULL) ? pswd - 1 : p;
1758-
1759-
if (tmp > begin) {
1760-
status = lxb_url_percent_encode_after_utf_8(begin, tmp,
1761-
&url->username, url->mraw,
1762-
LXB_URL_MAP_USERINFO, false);
1763-
if (status != LXB_STATUS_OK) {
1764-
lxb_url_parse_return(orig_data, buf, status);
1765-
}
1756+
tmp = (pswd != NULL) ? pswd - 1 : p;
1757+
if (tmp > begin) {
1758+
status = lxb_url_percent_encode_after_utf_8(begin, tmp,
1759+
&url->username, url->mraw,
1760+
LXB_URL_MAP_USERINFO, false);
1761+
if (status != LXB_STATUS_OK) {
1762+
lxb_url_parse_return(orig_data, buf, status);
17661763
}
17671764
}
17681765

@@ -5106,6 +5103,8 @@ lxb_url_search_params_parse(lxb_url_search_params_t *search_params,
51065103
return status;
51075104
}
51085105

5106+
last = entry;
5107+
51095108
lexbor_str_init(&entry->value, mraw, 0);
51105109
if (entry->value.data == NULL) {
51115110
return LXB_STATUS_ERROR_MEMORY_ALLOCATION;

ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
22
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
33
Date: Sat, 26 Aug 2023 15:08:59 +0200
4-
Subject: [PATCH 01/10] Expose line and column information for use in PHP
4+
Subject: [PATCH 01/15] Expose line and column information for use in PHP
55

66
---
77
source/lexbor/dom/interfaces/node.h | 2 ++

ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
22
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
33
Date: Mon, 14 Aug 2023 20:18:51 +0200
4-
Subject: [PATCH 02/10] Track implied added nodes for options use in PHP
4+
Subject: [PATCH 02/15] Track implied added nodes for options use in PHP
55

66
---
77
source/lexbor/html/tree.h | 3 +++

ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
22
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
33
Date: Thu, 24 Aug 2023 22:57:48 +0200
4-
Subject: [PATCH 03/10] Patch utilities and data structure to be able to
4+
Subject: [PATCH 03/15] Patch utilities and data structure to be able to
55
generate smaller lookup tables
66

77
Changed the generation script to check if everything fits in 32-bits.

ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
22
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
33
Date: Wed, 29 Nov 2023 21:26:47 +0100
4-
Subject: [PATCH 04/10] Remove unused upper case tag static data
4+
Subject: [PATCH 04/15] Remove unused upper case tag static data
55

66
---
77
source/lexbor/tag/res.h | 2 ++

0 commit comments

Comments
 (0)