From 1bc83897638740651a11b35a946f0e4e27e59231 Mon Sep 17 00:00:00 2001 From: youknowriad Date: Fri, 30 Nov 2018 20:58:46 +0000 Subject: [PATCH] Block Editor: Update @wordpress package dependencies. Updated packages - @wordpress/block-library@2.2.9 - @wordpress/block-serialization-default-parser@2.0.1 - @wordpress/block-serialization-spec-parser@2.0.1 - @wordpress/blocks@6.0.3 - @wordpress/edit-post@3.1.4 - @wordpress/editor@9.0.4 - @wordpress/format-library@1.2.7 Other changes: - Backport the parser changes. Fixes #45145. Built from https://develop.svn.wordpress.org/branches/5.0@43955 git-svn-id: http://core.svn.wordpress.org/branches/5.0@43787 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-block-parser.php | 8 ++- .../block-serialization-default-parser.js | 50 +++++++++++++++++-- .../block-serialization-default-parser.min.js | 2 +- wp-includes/script-loader.php | 12 ++--- wp-includes/version.php | 2 +- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/wp-includes/class-wp-block-parser.php b/wp-includes/class-wp-block-parser.php index c9fa5db1f3..216cb9a5f7 100644 --- a/wp-includes/class-wp-block-parser.php +++ b/wp-includes/class-wp-block-parser.php @@ -359,6 +359,7 @@ class WP_Block_Parser { * * @internal * @since 3.8.0 + * @since 4.6.1 fixed a bug in attribute parsing which caused catastrophic backtracking on invalid block comments * @return array */ function next_token() { @@ -373,13 +374,18 @@ class WP_Block_Parser { * match back in PHP to see which one it was. */ $has_match = preg_match( - '/).)*?}\s+)?(?\/)?-->/s', + '/).)*+)?}\s+)?(?\/)?-->/s', $this->document, $matches, PREG_OFFSET_CAPTURE, $this->offset ); + // if we get here we probably have catastrophic backtracking or out-of-memory in the PCRE + if ( false === $has_match ) { + return array( 'no-more-tokens', null, null, null, null ); + } + // we have no more tokens if ( 0 === $has_match ) { return array( 'no-more-tokens', null, null, null, null ); diff --git a/wp-includes/js/dist/block-serialization-default-parser.js b/wp-includes/js/dist/block-serialization-default-parser.js index 9e58759f1a..ccebcdb07d 100644 --- a/wp-includes/js/dist/block-serialization-default-parser.js +++ b/wp-includes/js/dist/block-serialization-default-parser.js @@ -99,7 +99,49 @@ var document; var offset; var output; var stack; -var tokenizer = /)[^])*?}\s+)?(\/)?-->/g; +/** + * Matches block comment delimiters + * + * While most of this pattern is straightforward the attribute parsing + * incorporates a tricks to make sure we don't choke on specific input + * + * - since JavaScript has no possessive quantifier or atomic grouping + * we are emulating it with a trick + * + * we want a possessive quantifier or atomic group to prevent backtracking + * on the `}`s should we fail to match the remainder of the pattern + * + * we can emulate this with a positive lookahead and back reference + * (a++)*c === ((?=(a+))\1)*c + * + * let's examine an example: + * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps + * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps + * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps + * + * this is because the possessive `++` and the atomic group `(?>)` + * tell the engine that all those `a`s belong together as a single group + * and so it won't split it up when stepping backwards to try and match + * + * if we use /((?=(a+))\1)*c/ then we get the same behavior as the atomic group + * or possessive and prevent the backtracking because the `a+` is matched but + * not captured. thus, we find the long string of `a`s and remember it, then + * reference it as a whole unit inside our pattern + * + * @cite http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead + * @cite http://blog.stevenlevithan.com/archives/mimic-atomic-groups + * @cite https://javascript.info/regexp-infinite-backtracking-problem + * + * once browsers reliably support atomic grouping or possessive + * quantifiers natively we should remove this trick and simplify + * + * @type RegExp + * + * @since 3.8.0 + * @since 4.6.1 added optimization to prevent backtracking on attribute parsing + */ + +var tokenizer = /)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g; function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) { return { @@ -275,13 +317,15 @@ function nextToken() { var startedAt = matches.index; - var _matches = Object(_babel_runtime_helpers_esm_slicedToArray__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])(matches, 6), + var _matches = Object(_babel_runtime_helpers_esm_slicedToArray__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])(matches, 7), match = _matches[0], closerMatch = _matches[1], namespaceMatch = _matches[2], nameMatch = _matches[3], attrsMatch = _matches[4], - voidMatch = _matches[5]; + + /* internal/unused */ + voidMatch = _matches[6]; var length = match.length; var isCloser = !!closerMatch; diff --git a/wp-includes/js/dist/block-serialization-default-parser.min.js b/wp-includes/js/dist/block-serialization-default-parser.min.js index de415ead90..efc64cfb37 100644 --- a/wp-includes/js/dist/block-serialization-default-parser.min.js +++ b/wp-includes/js/dist/block-serialization-default-parser.min.js @@ -1 +1 @@ -this.wp=this.wp||{},this.wp.blockSerializationDefaultParser=function(n){var t={};function r(e){if(t[e])return t[e].exports;var u=t[e]={i:e,l:!1,exports:{}};return n[e].call(u.exports,u,u.exports,r),u.l=!0,u.exports}return r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:e})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,t){if(1&t&&(n=r(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var e=Object.create(null);if(r.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var u in n)r.d(e,u,function(t){return n[t]}.bind(null,u));return e},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},r.p="",r(r.s=197)}({197:function(n,t,r){"use strict";r.r(t),r.d(t,"parse",function(){return a});var e,u,o,i,l=r(25),c=/)[^])*?}\s+)?(\/)?-->/g;function s(n,t,r,e,u){return{blockName:n,attrs:t,innerBlocks:r,innerHTML:e,innerContent:u}}function f(n){return s(null,{},[],n,[n])}var a=function(n){e=n,u=0,o=[],i=[],c.lastIndex=0;do{}while(p());return o};function p(){var n=function(){var n=c.exec(e);if(null===n)return["no-more-tokens"];var t=n.index,r=Object(l.a)(n,6),u=r[0],o=r[1],i=r[2],s=r[3],f=r[4],a=r[5],p=u.length,b=!!o,v=!!a,d=(i||"core/")+s,h=!!f,k=h?function(n){try{return JSON.parse(n)}catch(n){return null}}(f):{};if(v)return["void-block",d,k,t,p];if(b)return["block-closer",d,null,t,p];return["block-opener",d,k,t,p]}(),t=Object(l.a)(n,5),r=t[0],a=t[1],p=t[2],h=t[3],k=t[4],y=i.length,O=h>u?u:null;switch(r){case"no-more-tokens":if(0===y)return b(),!1;if(1===y)return d(),!1;for(;0)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g;function s(n,t,r,e,u){return{blockName:n,attrs:t,innerBlocks:r,innerHTML:e,innerContent:u}}function f(n){return s(null,{},[],n,[n])}var a=function(n){e=n,u=0,o=[],i=[],c.lastIndex=0;do{}while(p());return o};function p(){var n=function(){var n=c.exec(e);if(null===n)return["no-more-tokens"];var t=n.index,r=Object(l.a)(n,7),u=r[0],o=r[1],i=r[2],s=r[3],f=r[4],a=r[6],p=u.length,b=!!o,v=!!a,d=(i||"core/")+s,h=!!f,k=h?function(n){try{return JSON.parse(n)}catch(n){return null}}(f):{};if(v)return["void-block",d,k,t,p];if(b)return["block-closer",d,null,t,p];return["block-opener",d,k,t,p]}(),t=Object(l.a)(n,5),r=t[0],a=t[1],p=t[2],h=t[3],k=t[4],y=i.length,O=h>u?u:null;switch(r){case"no-more-tokens":if(0===y)return b(),!1;if(1===y)return d(),!1;for(;0 '1.0.3', 'autop' => '2.0.2', 'blob' => '2.1.0', - 'block-library' => '2.2.8', - 'block-serialization-default-parser' => '2.0.0', - 'blocks' => '6.0.2', + 'block-library' => '2.2.9', + 'block-serialization-default-parser' => '2.0.1', + 'blocks' => '6.0.3', 'components' => '7.0.3', 'compose' => '3.0.0', 'core-data' => '2.0.14', @@ -223,11 +223,11 @@ function wp_default_packages_scripts( &$scripts ) { 'deprecated' => '2.0.3', 'dom' => '2.0.7', 'dom-ready' => '2.0.2', - 'edit-post' => '3.1.3', - 'editor' => '9.0.3', + 'edit-post' => '3.1.4', + 'editor' => '9.0.4', 'element' => '2.1.8', 'escape-html' => '1.0.1', - 'format-library' => '1.2.6', + 'format-library' => '1.2.7', 'hooks' => '2.0.3', 'html-entities' => '2.0.3', 'i18n' => '3.1.0', diff --git a/wp-includes/version.php b/wp-includes/version.php index b333d0056b..d6405bfc35 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '5.0-RC1-43954'; +$wp_version = '5.0-RC1-43955'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.