Skip to content

Commit

Permalink
More documentation and a change from boolean to context indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
dmsnell committed Apr 26, 2024
1 parent 1a59f60 commit f991add
Showing 1 changed file with 59 additions and 12 deletions.
71 changes: 59 additions & 12 deletions src/wp-includes/html-api/class-wp-html-decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,33 @@ public static function decode_attribute( $text, $at = 0, $length = null ) {
}

/**
* Decodes a span of HTML text, respecting the ambiguous ampersand rule.
* Decodes a span of HTML text, depending on the context in which it's found.
*
* @param $allow_ambiguous_ampersands
* @param $text
* @param $at
* @param $length
* @return mixed|string
* This is a low-level method; prefer calling WP_HTML_Decoder::decode_attribute() or
* WP_HTML_Decoder::decode_text_node() instead.
*
* Example:
*
* '©' = WP_HTML_Decoder::decode( 'data', '©' );
*
* Use the `$at` and `$length` parameters to avoid string allocations when decoding a span
* of text found within a larger document.
*
* Example:
*
* $link = WP_HTML_Decoder::decode( 'attribute', '<a href="http&colon;//wordpress.org">Click</a>', 9, 26 );
* $link === 'http://wordpress.org';
*
* @since 6.6.0
*
* @param string $context `attribute` for decoding attribute values, `data` otherwise.
* @param string $text Text document containing span of text to decode.
* @param ?int $at Byte offset into text where span begins, defaults to the beginning.
* @param ?int $length How many bytes the portion of the text spans.
* The default value spans to the end of the text.
* @return string Decoded string.
*/
public static function decode( $allow_ambiguous_ampersands, $text, $at = 0, $length = null ) {
public static function decode( $context, $text, $at = 0, $length = null ) {
$decoded = '';
$end = isset( $length ) ? $at + $length : strlen( $text );
$was_at = $at;
Expand All @@ -171,7 +189,7 @@ public static function decode( $allow_ambiguous_ampersands, $text, $at = 0, $len
break;
}

$character_reference = self::read_character_reference( $text, $next_character_reference_at, $allow_ambiguous_ampersands, $skip_bytes );
$character_reference = self::read_character_reference( $context, $text, $next_character_reference_at, $skip_bytes );
if ( isset( $character_reference ) ) {
$at = $next_character_reference_at;
$decoded .= substr( $text, $was_at, $at - $was_at );
Expand All @@ -195,7 +213,36 @@ public static function decode( $allow_ambiguous_ampersands, $text, $at = 0, $len
return $decoded;
}

public static function read_character_reference( $text, $at, $allow_ambiguous_ampersand, &$skip_bytes ) {
/**
* Attempt to read a character reference at the given location in a given string,
* depending on the context in which it's found.
*
* If a character reference is found, this function will return the translated value
* that the reference maps to. It will then set in `$skip_bytes` how many bytes of
* input it read while consuming the character reference. This gives calling code the
* opportunity to advance its cursor when traversing a string and decoding. It
* indicates how long the character reference was.
*
* Example:
*
* null === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships&hellip;', 0 );
* '…' === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships&hellip;', 5, $skip_bytes );
* 8 === $skip_bytes;
*
* null === WP_HTML_Decoder::read_character_reference( 'attribute', '&notin;', 0 );
* '¬' === WP_HTML_Decoder::read_character_reference( 'attribute', '&notin;', 0, $skip_bytes );
* 4 === $skip_bytes;
*
* @since 6.6.0
*
* @param string $context `attribute` for decoding attribute values, `data` otherwise.
* @param string $text Text document containing span of text to decode.
* @param ?int $at Byte offset into text where span begins, defaults to the beginning.
* @param ?int $skip_bytes How many bytes the decodable portion of the text spans.
* The default value spans to the end of the text.
* @return string|null Decoded character reference if found, otherwise `false`.
*/
public static function read_character_reference( $context, $text, $at, &$skip_bytes = null ) {
global $html5_named_character_entity_set;

$length = strlen( $text );
Expand Down Expand Up @@ -375,9 +422,9 @@ public static function read_character_reference( $text, $at, $allow_ambiguous_am
}

/*
* At this point though have matched an entry in the named
* At this point though there's a match for an entry in the named
* character reference table but the match doesn't end in `;`.
* We need to determine if the next letter makes it an ambiguous.
* It may be allowed if it's followed by something unambiguous.
*/
$ambiguous_follower = (
$after_name < $length &&
Expand All @@ -394,7 +441,7 @@ public static function read_character_reference( $text, $at, $allow_ambiguous_am
return $name;
}

if ( ! $allow_ambiguous_ampersand ) {
if ( 'attribute' === $context ) {
return null;
}

Expand Down

0 comments on commit f991add

Please sign in to comment.