diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 1763142167211..3ac0a48a93f78 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -520,7 +520,12 @@ private function _process_directives( string $html ) { array_pop( $tag_stack ); } } else { - if ( 0 !== count( $p->get_attribute_names_with_prefix( 'data-wp-each-child' ) ) ) { + $each_child_attrs = $p->get_attribute_names_with_prefix( 'data-wp-each-child' ); + if ( null === $each_child_attrs ) { + continue; + } + + if ( null !== $each_child_attrs && 0 !== count( $each_child_attrs ) ) { /* * If the tag has a `data-wp-each-child` directive, jump to its closer * tag because those tags have already been processed. diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php index d674f5e54ce06..3ef06bb2e62f7 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php @@ -12,6 +12,34 @@ * @coversDefaultClass WP_Interactivity_API_Directives_Processor */ class Tests_Interactivity_API_WpInteractivityAPIDirectivesProcessor extends WP_UnitTestCase { + + /** + * Regression: _process_directives should not fatal when encountering malformed markup + * (e.g., a stray ) that causes get_attribute_names_with_prefix() to return null. + * + * Before the fix: PHP 8+ threw a TypeError from count(null). + */ + public function test_process_directives_handles_noncountable_each_child_attrs() { + $html = '