-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fix block validation: wrap in exception handler for malformed HTML #8304
Changes from 5 commits
c05b33d
c336990
bba75c8
54e5d09
192160e
97da31c
91faa6a
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 |
---|---|---|
|
@@ -380,8 +380,27 @@ export function getNextNonWhitespaceToken( tokens ) { | |
} | ||
|
||
/** | ||
* Returns true if there is given HTML strings are effectively equivalent, or | ||
* false otherwise. | ||
* Tokenize an HTML string, gracefully handling any errors thrown during | ||
* underlying tokenization. | ||
* | ||
* @param {string} html HTML string to tokenize. | ||
* | ||
* @return {Object[]|boolean} Array of valid tokenized HTML elements, or false | ||
*/ | ||
function getHTMLTokens( html ) { | ||
try { | ||
return tokenize( html ); | ||
} catch ( e ) { | ||
log.warning( 'Malformed HTML detected: %s', html ); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Returns true if the given HTML strings are effectively equivalent, or | ||
* false otherwise. Invalid HTML is not considered equivalent, even if the | ||
* strings directly match. | ||
* | ||
* @param {string} actual Actual HTML string. | ||
* @param {string} expected Expected HTML string. | ||
|
@@ -390,7 +409,12 @@ export function getNextNonWhitespaceToken( tokens ) { | |
*/ | ||
export function isEquivalentHTML( actual, expected ) { | ||
// Tokenize input content and reserialized save content | ||
const [ actualTokens, expectedTokens ] = [ actual, expected ].map( tokenize ); | ||
const [ actualTokens, expectedTokens ] = [ actual, expected ].map( getHTMLTokens ); | ||
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. I'm inclined to think this change could be simplified to something like: try {
const [
actualTokens,
expectedTokens,
] = [ actual, expected ].map( tokenize );
} catch ( error ) {
return false;
} Logging the warning about the specific string becomes a bit trickier. We could still have Or we could keep as-is. My only thought was avoiding the overloaded return value, where 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. AFAIK the const's are scoped to the try block so I don't think is possible unless they were converted to I've cleaned it up a bit already, and happy to make a further change, but otherwise will go as-is. 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. Good call. I guess the corrected form would look something closer to: let actualTokens, expectedTokens;
try {
( [
actualTokens,
expectedTokens,
] = [ actual, expected ].map( tokenize ) );
} catch ( error ) {
return false;
} Which starts to be a bit harder to read 😬 Good as it is. |
||
|
||
// If either is malformed then stop comparing - the strings are not equivalent | ||
if ( actualTokens === false || expectedTokens === false ) { | ||
return false; | ||
} | ||
|
||
let actualToken, expectedToken; | ||
while ( ( actualToken = getNextNonWhitespaceToken( actualTokens ) ) ) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation should describe in what cases the consumer would expect the function to return
false
. Currently it's not clear that this is tied to capturing errors.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside: Why was
false
chosen, vs. another more semantically meaningful value for empty likenull
orundefined
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force of habit from PHPland. Swapped to
null