Skip to content

Commit 9248888

Browse files
committed
Merge branch 'trunk' into html-api/set-mod-html-leading-newlines
2 parents 59e3f88 + 78d7382 commit 9248888

5 files changed

Lines changed: 128 additions & 5 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://develop.svn.wordpress.org/trunk"
88
},
99
"gutenberg": {
10-
"ref": "23b566c72e9c4a36219ef5d6e62890f05551f6cb"
10+
"ref": "022d8dd3d461f91b15c1f0410649d3ebb027207f"
1111
},
1212
"engines": {
1313
"node": ">=20.10.0",

src/wp-admin/includes/network.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ function network_step1( $errors = false ) {
198198
} else {
199199
$subdomain_install = false;
200200
$got_mod_rewrite = got_mod_rewrite();
201+
$message_class = '';
202+
$message = '';
203+
201204
if ( $got_mod_rewrite ) { // Dangerous assumptions.
202205
$message_class = 'updated';
203206
$message = '<p><strong>' . __( 'Warning:' ) . '</strong> ';

src/wp-includes/html-api/class-wp-html-processor.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,11 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
149149
* so this class constant from the Tag Processor is overwritten.
150150
*
151151
* @since 6.4.0
152+
* @since 7.0.0 Increased from 100 to 10,000
152153
*
153154
* @var int
154155
*/
155-
const MAX_BOOKMARKS = 100;
156+
const MAX_BOOKMARKS = 10_000;
156157

157158
/**
158159
* Holds the working state of the parser, including the stack of
@@ -1042,8 +1043,17 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool {
10421043
$token_name = $this->get_token_name();
10431044

10441045
if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) {
1046+
try {
1047+
$bookmark_name = $this->bookmark_token();
1048+
} catch ( Exception $e ) {
1049+
if ( self::ERROR_EXCEEDED_MAX_BOOKMARKS === $this->last_error ) {
1050+
return false;
1051+
}
1052+
throw $e;
1053+
}
1054+
10451055
$this->state->current_token = new WP_HTML_Token(
1046-
$this->bookmark_token(),
1056+
$bookmark_name,
10471057
$token_name,
10481058
$this->has_self_closing_flag(),
10491059
$this->release_internal_bookmark_on_destruct
@@ -1153,6 +1163,12 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool {
11531163
* otherwise might involve messier calling and return conventions.
11541164
*/
11551165
return false;
1166+
} catch ( Exception $e ) {
1167+
if ( self::ERROR_EXCEEDED_MAX_BOOKMARKS === $this->last_error ) {
1168+
return false;
1169+
}
1170+
// Rethrow any other exceptions for higher-level handling.
1171+
throw $e;
11561172
}
11571173
}
11581174

@@ -6315,6 +6331,8 @@ private function insert_foreign_element( WP_HTML_Token $token, bool $only_add_to
63156331
*
63166332
* @since 6.7.0
63176333
*
6334+
* @throws Exception When unable to allocate a bookmark for the next token in the input HTML document.
6335+
*
63186336
* @param string $token_name Name of token to create and insert into the stack of open elements.
63196337
* @param string|null $bookmark_name Optional. Name to give bookmark for created virtual node.
63206338
* Defaults to auto-creating a bookmark name.

src/wp-includes/version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
* @global string $wp_version
1818
*/
19-
$wp_version = '7.0-beta1-61709-src';
19+
$wp_version = '7.0-beta2-61752-src';
2020

2121
/**
2222
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

tests/phpunit/tests/html-api/wpHtmlProcessor.php

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ public function test_ensure_next_token_method_extensibility( $html, $expected_to
10681068
/**
10691069
* Ensure that lowercased tag_name query matches tags case-insensitively.
10701070
*
1071-
* @group 62427
1071+
* @ticket 62427
10721072
*/
10731073
public function test_next_tag_lowercase_tag_name() {
10741074
// The upper case <DIV> is irrelevant but illustrates the case-insentivity.
@@ -1079,4 +1079,106 @@ public function test_next_tag_lowercase_tag_name() {
10791079
$processor = WP_HTML_Processor::create_fragment( '<svg><RECT>' );
10801080
$this->assertTrue( $processor->next_tag( array( 'tag_name' => 'rect' ) ) );
10811081
}
1082+
1083+
/**
1084+
* Ensure that the processor does not throw errors in cases of extreme HTML nesting.
1085+
*
1086+
* @ticket 64394
1087+
*
1088+
* @expectedIncorrectUsage WP_HTML_Tag_Processor::set_bookmark
1089+
*/
1090+
public function test_deep_nesting_fails_process_without_error() {
1091+
$html = str_repeat( '<i>', WP_HTML_Processor::MAX_BOOKMARKS * 2 );
1092+
$processor = WP_HTML_Processor::create_fragment( $html );
1093+
1094+
while ( $processor->next_token() ) {
1095+
// Process tokens.
1096+
}
1097+
1098+
$this->assertSame(
1099+
WP_HTML_Processor::ERROR_EXCEEDED_MAX_BOOKMARKS,
1100+
$processor->get_last_error(),
1101+
'Failed to report exceeded-max-bookmarks error.'
1102+
);
1103+
}
1104+
1105+
/**
1106+
* @ticket 64394
1107+
*
1108+
* @expectedIncorrectUsage WP_HTML_Tag_Processor::set_bookmark
1109+
*/
1110+
public function test_deep_nesting_fails_processing_virtual_tokens_without_error() {
1111+
/*
1112+
* This test has some variability depending on how the virtual tokens align.
1113+
* In order to ensure that bookmarks are exhausted on a virtual token
1114+
* without throwing an error, 3 documents are parsed with different "offsets"
1115+
* to ensure that the bookmarks are exhaused on a virtual token in at least one of the runs.
1116+
*
1117+
* "<table><td><table><td>…" produces:
1118+
* └─TABLE (real)
1119+
* └─TBODY (virtual)
1120+
* └─TR (virtual)
1121+
* └─TD (real)
1122+
* └─TABLE (real)
1123+
* └─TBODY (virtual)
1124+
* └─TR (virtual)
1125+
* └─TD (real)
1126+
* └─…
1127+
*/
1128+
$html_table_td = str_repeat( '<table><td>', WP_HTML_Processor::MAX_BOOKMARKS * 2 );
1129+
1130+
// Offset 0
1131+
$processor = WP_HTML_Processor::create_fragment( $html_table_td );
1132+
while ( $processor->next_token() ) {
1133+
// Process tokens.
1134+
}
1135+
$this->assertSame(
1136+
WP_HTML_Processor::ERROR_EXCEEDED_MAX_BOOKMARKS,
1137+
$processor->get_last_error(),
1138+
'Failed to report exceeded-max-bookmarks error.'
1139+
);
1140+
1141+
// Offset 1
1142+
$processor = WP_HTML_Processor::create_fragment( "<div>{$html_table_td}" );
1143+
while ( $processor->next_token() ) {
1144+
// Process tokens.
1145+
}
1146+
$this->assertSame(
1147+
WP_HTML_Processor::ERROR_EXCEEDED_MAX_BOOKMARKS,
1148+
$processor->get_last_error(),
1149+
'Failed to report exceeded-max-bookmarks error.'
1150+
);
1151+
1152+
// Offset 2
1153+
$processor = WP_HTML_Processor::create_fragment( "<div><div>{$html_table_td}" );
1154+
while ( $processor->next_token() ) {
1155+
// Process tokens.
1156+
}
1157+
$this->assertSame(
1158+
WP_HTML_Processor::ERROR_EXCEEDED_MAX_BOOKMARKS,
1159+
$processor->get_last_error(),
1160+
'Failed to report exceeded-max-bookmarks error.'
1161+
);
1162+
}
1163+
1164+
/**
1165+
* @ticket 64394
1166+
*
1167+
* @expectedIncorrectUsage WP_HTML_Tag_Processor::set_bookmark
1168+
*/
1169+
public function test_prevents_unbounded_bookmarking() {
1170+
$processor = WP_HTML_Processor::create_full_parser( '<!DOCTYPE html><html>' );
1171+
$processor->next_tag();
1172+
1173+
// This might fail before the MAX_BOOKMARK limit, which is okay.
1174+
foreach ( range( 0, WP_HTML_Processor::MAX_BOOKMARKS ) as $n ) {
1175+
if ( ! $processor->set_bookmark( "{$n}" ) ) {
1176+
break;
1177+
}
1178+
}
1179+
1180+
$this->assertFalse(
1181+
$processor->set_bookmark( 'beyond the limit' )
1182+
);
1183+
}
10821184
}

0 commit comments

Comments
 (0)