From 2f608e30f5280033700e88a55d845fd4f710d190 Mon Sep 17 00:00:00 2001 From: John Godley Date: Mon, 17 Sep 2018 13:53:39 +0100 Subject: [PATCH 1/7] Add greater than to attribute escaping Although > is a valid attribute character it is used in wptexturize to split HTML tokens. Without escaping wptexturize will incorrectly tokenize a string, causing problems for everything else. Encoding it in Gutenberg prevents this problem while being transparent to the Gutenberg visual UI. --- packages/element/src/test/index.js | 2 +- packages/element/src/test/serialize.js | 2 +- packages/escape-html/src/index.js | 13 ++++++++++++- packages/escape-html/src/test/index.js | 13 +++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/element/src/test/index.js b/packages/element/src/test/index.js index 5d8417859042df..ef5bd4bb87542b 100644 --- a/packages/element/src/test/index.js +++ b/packages/element/src/test/index.js @@ -53,7 +53,7 @@ describe( 'element', () => { }, '<"WordPress" & Friends>' ) ); expect( result ).toBe( - '' + + '' + '<"WordPress" & Friends>' + '' ); diff --git a/packages/element/src/test/serialize.js b/packages/element/src/test/serialize.js index d0f5d9ef32b3ac..7fe4251666decd 100644 --- a/packages/element/src/test/serialize.js +++ b/packages/element/src/test/serialize.js @@ -528,7 +528,7 @@ describe( 'renderAttributes()', () => { href: '/index.php?foo=bar&qux=<"scary">', } ); - expect( result ).toBe( ' style="background:url("foo.png")" href="/index.php?foo=bar&qux=<"scary">"' ); + expect( result ).toBe( ' style="background:url("foo.png")" href="/index.php?foo=bar&qux=<"scary">"' ); } ); it( 'should render numeric attributes', () => { diff --git a/packages/escape-html/src/index.js b/packages/escape-html/src/index.js index 6b3f74e834564d..8bcc0a61da631f 100644 --- a/packages/escape-html/src/index.js +++ b/packages/escape-html/src/index.js @@ -51,6 +51,17 @@ export function escapeLessThan( value ) { return value.replace( //g, '>' ); +} + /** * Returns an escaped attribute value. * @@ -64,7 +75,7 @@ export function escapeLessThan( value ) { * @return {string} Escaped attribute value. */ export function escapeAttribute( value ) { - return escapeQuotationMark( escapeAmpersand( value ) ); + return escapeGreaterThan( escapeQuotationMark( escapeAmpersand( value ) ) ); } /** diff --git a/packages/escape-html/src/test/index.js b/packages/escape-html/src/test/index.js index 65b3e09dfcfe19..60a35126d04633 100644 --- a/packages/escape-html/src/test/index.js +++ b/packages/escape-html/src/test/index.js @@ -5,11 +5,19 @@ import { escapeAmpersand, escapeQuotationMark, escapeLessThan, + escapeGreaterThan, escapeAttribute, escapeHTML, isValidAttributeName, } from '../'; +function testEscapeGreaterThan( implementation ) { + it( 'should escape greater than', () => { + const result = implementation( 'Chicken > Ribs' ); + expect( result ).toBe( 'Chicken > Ribs' ); + } ); +} + function testEscapeAmpersand( implementation ) { it( 'should escape ampersand', () => { const result = implementation( 'foo & bar & & baz Σ &#bad; Σ Σ vil;' ); @@ -46,9 +54,14 @@ describe( 'escapeLessThan', () => { testEscapeLessThan( escapeLessThan ); } ); +describe( 'escapeGreaterThan', () => { + testEscapeGreaterThan( escapeGreaterThan ); +} ); + describe( 'escapeAttribute', () => { testEscapeAmpersand( escapeAttribute ); testEscapeQuotationMark( escapeAttribute ); + testEscapeGreaterThan( escapeAttribute ); } ); describe( 'escapeHTML', () => { From dfdd1f548a647c0b129f8cc2747ed5b4bfe712b4 Mon Sep 17 00:00:00 2001 From: John Godley Date: Mon, 26 Nov 2018 14:39:58 +0000 Subject: [PATCH 2/7] Add comment about encoding difference --- packages/escape-html/src/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/escape-html/src/index.js b/packages/escape-html/src/index.js index 8bcc0a61da631f..b506b2101f98a1 100644 --- a/packages/escape-html/src/index.js +++ b/packages/escape-html/src/index.js @@ -52,7 +52,7 @@ export function escapeLessThan( value ) { } /** - * Returns a string with grater-than sign replaced. + * Returns a string with greater-than sign replaced. * * @param {string} value Original string. * @@ -70,6 +70,9 @@ export function escapeGreaterThan( value ) { * "[...] the text cannot contain an ambiguous ampersand [...] must not contain * any literal U+0022 QUOTATION MARK characters (")" * + * Note we also escape the greater than symbol, as this is used by wptexturize to + * split HTML strings. This is a WordPress specific fix + * * @param {string} value Attribute value. * * @return {string} Escaped attribute value. From 384e41ac6d4457515ff531c19a0d9a1109ff2ee3 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 4 Dec 2018 10:13:06 +0000 Subject: [PATCH 3/7] Improve escapeGreaterThan comment to refer to trac ticket Co-Authored-By: johngodley --- packages/escape-html/src/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/escape-html/src/index.js b/packages/escape-html/src/index.js index b506b2101f98a1..0b4e99941a41e0 100644 --- a/packages/escape-html/src/index.js +++ b/packages/escape-html/src/index.js @@ -73,6 +73,10 @@ export function escapeGreaterThan( value ) { * Note we also escape the greater than symbol, as this is used by wptexturize to * split HTML strings. This is a WordPress specific fix * + * Note that if a resolution for Trac#45387 comes to fruition, it is no longer + * necessary for `escapeGreaterThan` to exist in this module. + * + * See: https://core.trac.wordpress.org/ticket/45387 * @param {string} value Attribute value. * * @return {string} Escaped attribute value. From da3ab97d5b68e4c014f79ac69b47e15341e5f8f6 Mon Sep 17 00:00:00 2001 From: John Godley Date: Tue, 4 Dec 2018 10:19:35 +0000 Subject: [PATCH 4/7] Make escapeGreaterThan an unstable API function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don’t want people using it --- packages/escape-html/src/index.js | 6 +++--- packages/escape-html/src/test/index.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/escape-html/src/index.js b/packages/escape-html/src/index.js index 0b4e99941a41e0..038e854d72194a 100644 --- a/packages/escape-html/src/index.js +++ b/packages/escape-html/src/index.js @@ -58,7 +58,7 @@ export function escapeLessThan( value ) { * * @return {string} Escaped string. */ -export function escapeGreaterThan( value ) { +export function __unstableEscapeGreaterThan( value ) { return value.replace( />/g, '>' ); } @@ -74,7 +74,7 @@ export function escapeGreaterThan( value ) { * split HTML strings. This is a WordPress specific fix * * Note that if a resolution for Trac#45387 comes to fruition, it is no longer - * necessary for `escapeGreaterThan` to exist in this module. + * necessary for `__unstableEscapeGreaterThan` to exist in this module. * * See: https://core.trac.wordpress.org/ticket/45387 * @param {string} value Attribute value. @@ -82,7 +82,7 @@ export function escapeGreaterThan( value ) { * @return {string} Escaped attribute value. */ export function escapeAttribute( value ) { - return escapeGreaterThan( escapeQuotationMark( escapeAmpersand( value ) ) ); + return __unstableEscapeGreaterThan( escapeQuotationMark( escapeAmpersand( value ) ) ); } /** diff --git a/packages/escape-html/src/test/index.js b/packages/escape-html/src/test/index.js index 60a35126d04633..f6a3404dc92783 100644 --- a/packages/escape-html/src/test/index.js +++ b/packages/escape-html/src/test/index.js @@ -5,13 +5,13 @@ import { escapeAmpersand, escapeQuotationMark, escapeLessThan, - escapeGreaterThan, + __unstableEscapeGreaterThan, escapeAttribute, escapeHTML, isValidAttributeName, } from '../'; -function testEscapeGreaterThan( implementation ) { +function testUnstableEscapeGreaterThan( implementation ) { it( 'should escape greater than', () => { const result = implementation( 'Chicken > Ribs' ); expect( result ).toBe( 'Chicken > Ribs' ); @@ -55,13 +55,13 @@ describe( 'escapeLessThan', () => { } ); describe( 'escapeGreaterThan', () => { - testEscapeGreaterThan( escapeGreaterThan ); + testUnstableEscapeGreaterThan( __unstableEscapeGreaterThan ); } ); describe( 'escapeAttribute', () => { testEscapeAmpersand( escapeAttribute ); testEscapeQuotationMark( escapeAttribute ); - testEscapeGreaterThan( escapeAttribute ); + testUnstableEscapeGreaterThan( escapeAttribute ); } ); describe( 'escapeHTML', () => { From 59cf1ad3828f3271a77a71d546ba940de579f29f Mon Sep 17 00:00:00 2001 From: John Godley Date: Mon, 28 Jan 2019 15:38:38 +0000 Subject: [PATCH 5/7] Move escapeGreater into seperate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s available internally and for testing, but isn’t exported outside of the package --- packages/escape-html/src/escape-greater.js | 15 +++++++++++++++ packages/escape-html/src/index.js | 19 +++++++------------ packages/escape-html/src/test/index.js | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 packages/escape-html/src/escape-greater.js diff --git a/packages/escape-html/src/escape-greater.js b/packages/escape-html/src/escape-greater.js new file mode 100644 index 00000000000000..f761a81e16ae61 --- /dev/null +++ b/packages/escape-html/src/escape-greater.js @@ -0,0 +1,15 @@ +/** + * Returns a string with greater-than sign replaced. + * + * Note that if a resolution for Trac#45387 comes to fruition, it is no longer + * necessary for `__unstableEscapeGreaterThan` to exist. + * + * See: https://core.trac.wordpress.org/ticket/45387 + * + * @param {string} value Original string. + * + * @return {string} Escaped string. + */ +export default function __unstableEscapeGreaterThan( value ) { + return value.replace( />/g, '>' ); +} diff --git a/packages/escape-html/src/index.js b/packages/escape-html/src/index.js index 038e854d72194a..c29efb94bd2d04 100644 --- a/packages/escape-html/src/index.js +++ b/packages/escape-html/src/index.js @@ -1,3 +1,8 @@ +/** + * Internal dependencies + */ +import __unstableEscapeGreaterThan from './escape-greater'; + /** * Regular expression matching invalid attribute names. * @@ -51,17 +56,6 @@ export function escapeLessThan( value ) { return value.replace( //g, '>' ); -} - /** * Returns an escaped attribute value. * @@ -74,9 +68,10 @@ export function __unstableEscapeGreaterThan( value ) { * split HTML strings. This is a WordPress specific fix * * Note that if a resolution for Trac#45387 comes to fruition, it is no longer - * necessary for `__unstableEscapeGreaterThan` to exist in this module. + * necessary for `__unstableEscapeGreaterThan` to be used. * * See: https://core.trac.wordpress.org/ticket/45387 + * * @param {string} value Attribute value. * * @return {string} Escaped attribute value. diff --git a/packages/escape-html/src/test/index.js b/packages/escape-html/src/test/index.js index f6a3404dc92783..9558c58c7e23ab 100644 --- a/packages/escape-html/src/test/index.js +++ b/packages/escape-html/src/test/index.js @@ -5,11 +5,11 @@ import { escapeAmpersand, escapeQuotationMark, escapeLessThan, - __unstableEscapeGreaterThan, escapeAttribute, escapeHTML, isValidAttributeName, } from '../'; +import __unstableEscapeGreaterThan from '../escape-greater'; function testUnstableEscapeGreaterThan( implementation ) { it( 'should escape greater than', () => { From 7892dba41ba5adc40376b1e76a3c4288f919f89a Mon Sep 17 00:00:00 2001 From: John Godley Date: Mon, 28 Jan 2019 15:38:59 +0000 Subject: [PATCH 6/7] Update version and changelog --- packages/escape-html/CHANGELOG.md | 4 ++++ packages/escape-html/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/escape-html/CHANGELOG.md b/packages/escape-html/CHANGELOG.md index e780b87752277f..3d81e8ec35b7b5 100644 --- a/packages/escape-html/CHANGELOG.md +++ b/packages/escape-html/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.1 (Unreleased) + +- Add fix for WordPress wptexturize greater-than tokenize bug (see https://core.trac.wordpress.org/ticket/45387) + ## 1.0.1 (2018-10-19) ## 1.0.0 (2018-10-18) diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index 909f2bd4ec1f3e..a496c52e213bc2 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "1.1.0", + "version": "1.1.1", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 7f6b6d2edf5a3f18e6586f10615ff97144e75324 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 18 Mar 2019 08:35:34 +0100 Subject: [PATCH 7/7] Update the docs --- packages/escape-html/README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/escape-html/README.md b/packages/escape-html/README.md index d144be1b7de9f6..eafa8cf0673b71 100644 --- a/packages/escape-html/README.md +++ b/packages/escape-html/README.md @@ -18,7 +18,7 @@ _This package assumes that your code will run in an **ES2015+** environment. If ### escapeAmpersand -[src/index.js#L28-L30](src/index.js#L28-L30) +[src/index.js#L33-L35](src/index.js#L33-L35) Returns a string with ampersands escaped. Note that this is an imperfect implementation, where only ampersands which do not appear as a pattern of @@ -41,7 +41,7 @@ named references (i.e. ambiguous ampersand) are are still permitted. ### escapeAttribute -[src/index.js#L66-L68](src/index.js#L66-L68) +[src/index.js#L79-L81](src/index.js#L79-L81) Returns an escaped attribute value. @@ -52,6 +52,14 @@ Returns an escaped attribute value. "[...] the text cannot contain an ambiguous ampersand [...] must not contain any literal U+0022 QUOTATION MARK characters (")" +Note we also escape the greater than symbol, as this is used by wptexturize to +split HTML strings. This is a WordPress specific fix + +Note that if a resolution for Trac#45387 comes to fruition, it is no longer +necessary for `__unstableEscapeGreaterThan` to be used. + +See: + **Parameters** - **value** `string`: Attribute value. @@ -62,7 +70,7 @@ any literal U+0022 QUOTATION MARK characters (")" ### escapeHTML -[src/index.js#L82-L84](src/index.js#L82-L84) +[src/index.js#L95-L97](src/index.js#L95-L97) Returns an escaped HTML element value. @@ -83,7 +91,7 @@ ambiguous ampersand." ### escapeLessThan -[src/index.js#L50-L52](src/index.js#L50-L52) +[src/index.js#L55-L57](src/index.js#L55-L57) Returns a string with less-than sign replaced. @@ -97,7 +105,7 @@ Returns a string with less-than sign replaced. ### escapeQuotationMark -[src/index.js#L39-L41](src/index.js#L39-L41) +[src/index.js#L44-L46](src/index.js#L44-L46) Returns a string with quotation marks replaced. @@ -111,7 +119,7 @@ Returns a string with quotation marks replaced. ### isValidAttributeName -[src/index.js#L93-L95](src/index.js#L93-L95) +[src/index.js#L106-L108](src/index.js#L106-L108) Returns true if the given attribute name is valid, or false otherwise.