Skip to content

Commit

Permalink
Fix escaping issues in editor and rendered block
Browse files Browse the repository at this point in the history
  • Loading branch information
donnapep committed Jul 28, 2020
1 parent d2a6435 commit d2c9996
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
13 changes: 7 additions & 6 deletions src/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import {
} from '@wordpress/components';
import { PlainText, InspectorControls } from '@wordpress/editor';

/**
* Internal dependencies
*/
import save from './save';

registerBlockType( 'syntaxhighlighter/code', {
title: __( 'SyntaxHighlighter Code', 'syntaxhighlighter' ),

Expand All @@ -38,7 +43,7 @@ registerBlockType( 'syntaxhighlighter/code', {
content: {
type: 'string',
source: 'text',
selector: 'pre',
selector: 'code',
},

language: {
Expand Down Expand Up @@ -296,9 +301,5 @@ registerBlockType( 'syntaxhighlighter/code', {
return [ blockSettings, editView ];
},

save( { attributes } ) {
const { content } = attributes;

return( <pre>{ content }</pre> );
},
save,
} );
12 changes: 12 additions & 0 deletions src/save.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Internal dependencies
*/
import { escape } from './utils';

export default function save( { attributes } ) {
return (
<pre>
<code>{ escape( attributes.content ) }</code>
</pre>
);
}
61 changes: 61 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* External dependencies
*/
import { flow } from 'lodash';

/**
* WordPress dependencies
*/
import { escapeEditableHTML } from '@wordpress/escape-html';

/**
* Escapes ampersands, shortcodes, and links.
*
* @param {string} content The content of a code block.
* @return {string} The given content with some characters escaped.
*/
export function escape( content ) {
return flow(
escapeEditableHTML,
escapeOpeningSquareBrackets,
escapeProtocolInIsolatedUrls
)( content || '' );
}

/**
* Returns the given content with all opening shortcode characters converted
* into their HTML entity counterpart (i.e. [ => &#91;). For instance, a
* shortcode like [embed] becomes &#91;embed]
*
* This function replicates the escaping of HTML tags, where a tag like
* <strong> becomes &lt;strong>.
*
* @param {string} content The content of a code block.
* @return {string} The given content with its opening shortcode characters
* converted into their HTML entity counterpart
* (i.e. [ => &#91;)
*/
function escapeOpeningSquareBrackets( content ) {
return content.replace( /\[/g, '&#91;' );
}

/**
* Converts the first two forward slashes of any isolated URL into their HTML
* counterparts (i.e. // => &#47;&#47;). For instance, https://youtube.com/watch?x
* becomes https:&#47;&#47;youtube.com/watch?x.
*
* An isolated URL is a URL that sits in its own line, surrounded only by spacing
* characters.
*
* See https://github.com/WordPress/wordpress-develop/blob/5.1.1/src/wp-includes/class-wp-embed.php#L403
*
* @param {string} content The content of a code block.
* @return {string} The given content with its ampersands converted into
* their HTML entity counterpart (i.e. & => &amp;)
*/
function escapeProtocolInIsolatedUrls( content ) {
return content.replace(
/^(\s*https?:)\/\/([^\s<>"]+\s*)$/m,
'$1&#47;&#47;$2'
);
}
3 changes: 2 additions & 1 deletion syntaxhighlighter.php
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,11 @@ public function render_block( $attributes, $content ) {
}
}

$code = preg_replace( '#<pre [^>]+>([^<]+)?</pre>#', '$1', $content );
$code = preg_replace( '#<pre [^>]+><code>([^<]+)?</code></pre>#', '$1', $content );

// Undo escaping done by WordPress
$code = str_replace( '&lt;', '<', $code );
$code = str_replace( '&amp;', '&', $code );

return $this->shortcode_callback( $attributes, $code, 'code' );
}
Expand Down

0 comments on commit d2c9996

Please sign in to comment.