-
Notifications
You must be signed in to change notification settings - Fork 3.2k
HTML API: Double escape character refs when setting attribute values #10143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
8d8622e
8e0d406
66af901
ff62be1
daef88f
c2e2ad4
5e5473a
40cfce5
1435b6e
b581113
0db1374
605b00d
00f01bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3757,7 +3757,16 @@ public function set_modifiable_text( string $plaintext_content ): bool { | |||||||||||||||||
| $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( | ||||||||||||||||||
| $this->text_starts_at, | ||||||||||||||||||
| $this->text_length, | ||||||||||||||||||
| htmlspecialchars( $plaintext_content, ENT_QUOTES | ENT_HTML5 ) | ||||||||||||||||||
| strtr( | ||||||||||||||||||
| $plaintext_content, | ||||||||||||||||||
| array( | ||||||||||||||||||
| '<' => '<', | ||||||||||||||||||
| '>' => '>', | ||||||||||||||||||
| '&' => '&', | ||||||||||||||||||
| '"' => '"', | ||||||||||||||||||
| "'" => ''', | ||||||||||||||||||
| ) | ||||||||||||||||||
| ) | ||||||||||||||||||
| ); | ||||||||||||||||||
|
|
||||||||||||||||||
| return true; | ||||||||||||||||||
|
|
@@ -3871,12 +3880,22 @@ static function ( $tag_match ) { | |||||||||||||||||
| /** | ||||||||||||||||||
| * Updates or creates a new attribute on the currently matched tag with the passed value. | ||||||||||||||||||
| * | ||||||||||||||||||
| * For boolean attributes special handling is provided: | ||||||||||||||||||
| * This function handles all necessary HTML encoding. Provide normal, unescaped string values. | ||||||||||||||||||
| * The HTML API will encode the strings appropriately so that the borwser interprets them to | ||||||||||||||||||
| * as then intended value. | ||||||||||||||||||
| * | ||||||||||||||||||
| * Example: | ||||||||||||||||||
| * | ||||||||||||||||||
| * // Renders “Eggs & Milk” in a browser, encoded as `Eggs & Milk`. | ||||||||||||||||||
| * $processor->set_attribute( 'title', 'Eggs & Milk' ); | ||||||||||||||||||
| * | ||||||||||||||||||
| * // Renders “Eggs & Milk” in a browser, encoded as `Eggs &amp; Milk`. | ||||||||||||||||||
| * $processor->set_attribute( 'title', 'Eggs & Milk' ); | ||||||||||||||||||
| * | ||||||||||||||||||
| * Special handling is provided for boolean attribute values: | ||||||||||||||||||
| * - When `true` is passed as the value, then only the attribute name is added to the tag. | ||||||||||||||||||
| * - When `false` is passed, the attribute gets removed if it existed before. | ||||||||||||||||||
| * | ||||||||||||||||||
| * For string attributes, the value is escaped using the `esc_attr` function. | ||||||||||||||||||
| * | ||||||||||||||||||
| * @since 6.2.0 | ||||||||||||||||||
| * @since 6.2.1 Fix: Only create a single update for multiple calls with case-variant attribute names. | ||||||||||||||||||
| * | ||||||||||||||||||
|
|
@@ -3950,12 +3969,23 @@ public function set_attribute( $name, $value ): bool { | |||||||||||||||||
| } else { | ||||||||||||||||||
| $comparable_name = strtolower( $name ); | ||||||||||||||||||
|
|
||||||||||||||||||
| /* | ||||||||||||||||||
| * Escape URL attributes. | ||||||||||||||||||
| /** | ||||||||||||||||||
| * Escape attribute values appropriately. | ||||||||||||||||||
| * | ||||||||||||||||||
| * @see https://html.spec.whatwg.org/#attributes-3 | ||||||||||||||||||
| */ | ||||||||||||||||||
| $escaped_new_value = in_array( $comparable_name, wp_kses_uri_attributes(), true ) ? esc_url( $value ) : esc_attr( $value ); | ||||||||||||||||||
| $escaped_new_value = in_array( $comparable_name, wp_kses_uri_attributes(), true ) | ||||||||||||||||||
| ? esc_url( $value ) | ||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The wordpress-develop/src/wp-includes/formatting.php Lines 4522 to 4527 in fe2b33f
To avoid that, I think using
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is only a formatting change, I broke the ternary onto three lines. Can we consider that suggestion in a separate ticket and PR?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah sure, but it it is related to the double-escaping issue, because var_dump( esc_url( 'http://example.com/?foo&bar' ) );
var_dump( esc_url( 'http://example.com/?foo&bar' ) );
var_dump( esc_url( 'http://example.com/?foo&bar' ) );All result in: string(32) "http://example.com/?foo&bar"
string(32) "http://example.com/?foo&bar"
string(32) "http://example.com/?foo&bar"I don't really see why a URI attribute should be treated differently at the HTML API layer. So this could instead just be:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're absolutely right that the double-escaping issue also exists in
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, sounds good. |
||||||||||||||||||
| : strtr( | ||||||||||||||||||
| $value, | ||||||||||||||||||
| array( | ||||||||||||||||||
| '<' => '<', | ||||||||||||||||||
| '>' => '>', | ||||||||||||||||||
| '&' => '&', | ||||||||||||||||||
| '"' => '"', | ||||||||||||||||||
| "'" => ''', | ||||||||||||||||||
| ) | ||||||||||||||||||
| ); | ||||||||||||||||||
|
|
||||||||||||||||||
| // If the escaping functions wiped out the update, reject it and indicate it was rejected. | ||||||||||||||||||
| if ( '' === $escaped_new_value && '' !== $value ) { | ||||||||||||||||||
|
|
||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.