Make WordPress Core

Opened 6 days ago

Last modified 6 days ago

#66492 new enhancement

Tests: Add unit coverage for the helper functions in kses.php

Reported by: hmbashar Owned by:
Priority: normal Milestone: Awaiting Review
Component: Formatting Version:
Severity: normal Keywords: has-patch has-unit-tests
Cc: Focuses: tests

Description

src/wp-includes/kses.php has a number of helper functions that are used by wp_kses() and its legacy parser but have no direct PHPUnit coverage. The existing tests in tests/phpunit/tests/kses/ and tests/phpunit/tests/kses.php cover the public entry points and some helpers (for example wp_kses_hair(), wp_kses_decode_entities() and wp_kses_check_attr_val()), but a search of tests/phpunit/tests finds no direct references to:

  • wp_kses_no_null()
  • wp_kses_bad_protocol_once()
  • wp_kses_array_lc()
  • wp_kses_named_entities()
  • wp_kses_normalize_entities2()
  • wp_kses_normalize_entities3()

Some of these are only exercised indirectly through wp_kses(), so a change in their behavior is hard to spot and to attribute. Direct tests describe the current behavior of each helper.

Proposed scope

Add tests under tests/phpunit/tests/kses/, one class per function, with data providers where it helps, for example:

  • wp_kses_no_null(): removal of NULL characters and of \0 sequences, and the slash_zero option (remove, keep).
  • wp_kses_bad_protocol_once(): allowed and disallowed protocols, uppercase and mixed case, and repeated or nested protocols.
  • wp_kses_array_lc(): lowercasing of attribute names, and preserving the values.
  • wp_kses_named_entities() and wp_kses_normalize_entities2() / 3(): valid named, decimal and hexadecimal references, invalid ones, and references that are out of range.

Out of scope

This ticket only adds tests and does not change behavior. The following are left out on purpose because other tickets are working on them:

  • wp_kses_split() and wp_kses_split2(), which belong to the legacy parser that #66208 replaces.
  • wp_kses_stripslashes(), which #63881 proposes to deprecate.
  • wp_filter_nohtml_kses(), see #54488.
  • The null input of wp_kses_no_null(), see #62785.

Related: #65819, #66208, #63881, #54488, #62785.

Change History (1)

This ticket was mentioned in ​PR #15527 on ​WordPress/wordpress-develop by ​@hmbashar.


6 days ago
#1

  • Keywords has-patch has-unit-tests added; needs-patch removed

Adds direct unit tests for six helper functions in src/wp-includes/kses.php that are used by wp_kses() and had no direct test coverage. Each function gets its own test class in tests/phpunit/tests/kses/. No behavior is changed.

Functions covered:

  • wp_kses_no_null()
    • Removal of control characters, while tab, line feed, carriage return, space and multibyte characters are kept.
    • The slash_zero option: escaped zeros are removed by default and for remove, and kept for any other value. Options that are null, empty or without slash_zero use the default.
  • wp_kses_bad_protocol_once() (and wp_kses_bad_protocol_once2())
    • Allowed protocols are kept and lowercased, and protocols that are not allowed are removed.
    • Content without a protocol, including a colon after a query, is not changed.
    • Encoded colons (decimal, hexadecimal and named, with and without the semicolon), whitespace, NULL characters and encoded characters in the protocol.
    • feed: URLs, their nesting limit and the $count argument.
  • wp_kses_array_lc()
    • Keys of both levels are lowercased, and values and their order are not changed.
  • wp_kses_named_entities()
    • Allowed names are kept, any other name has its ampersand escaped, and a missing name returns an empty string.
  • wp_kses_normalize_entities2() and wp_kses_normalize_entities3()
    • Valid references are normalized (padded to three digits for decimal, leading zeros removed for hexadecimal).
    • Invalid ones (control characters, surrogates, noncharacters, out of range) have their ampersand escaped.
    • The callbacks are also run with the patterns from wp_kses_normalize_entities().

The tests call the helpers directly, so they do not depend on whether wp_kses() uses the legacy parser or the HTML API based one. These functions are left out because other tickets are working on them: wp_kses_split() and wp_kses_split2() (#66208), wp_kses_stripslashes() (#63881), wp_filter_nohtml_kses() (#54488), and the null input of wp_kses_no_null() (#62785).

Testing:

  • vendor/bin/phpunit --filter Tests_Kses_
  • vendor/bin/phpunit -c tests/phpunit/multisite.xml --filter Tests_Kses_
  • vendor/bin/phpunit --group kses
  • vendor/bin/phpcs tests/phpunit/tests/kses/

I also temporarily broke the related lines in src/wp-includes/kses.php (the control character range, the slash_zero handling, the query check, the feed: depth, the encoded colon handling, the lowercasing, whitespace, NULL and entity decoding of the protocol, the key lowercasing, the allowed entity check, the padding, leading zero removal and the valid_unicode() checks) and confirmed that a new test fails for each one. Switching in_array() to a loose comparison in wp_kses_named_entities() cannot be detected, because the names are always strings.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Sonnet 5.5
Used for: Written with AI and manually reviewed by me.

Note: See TracTickets for help on using tickets.