diff --git a/lib/extend/tag.js b/lib/extend/tag.js index a0281a5cfa..875dc7b311 100644 --- a/lib/extend/tag.js +++ b/lib/extend/tag.js @@ -4,7 +4,7 @@ const { stripIndent } = require('hexo-util'); const { cyan } = require('chalk'); const { Environment } = require('nunjucks'); const Promise = require('bluebird'); -const rSwigRawFullBlock = /{% *raw *%}[\s\S]+{% *endraw *%}/; +const rSwigRawFullBlock = /{% *raw *%}/; const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); class NunjucksTag { @@ -228,11 +228,11 @@ class Tag { options = {}; } - str = str.replace(/]*>([\s\S]+?)<\/code>/gm, (str, code) => { + str = str.replace(/]*>[\s\S]+?<\/code>/g, str => { // https://hexo.io/docs/tag-plugins#Raw + // https://mozilla.github.io/nunjucks/templating.html#raw // Only escape code block when there is no raw tag included - if (rSwigRawFullBlock.test(code)) return str; - return escapeSwigTag(str); + return rSwigRawFullBlock.test(str) ? str : escapeSwigTag(str); }); return Promise.fromCallback(cb => { this.env.renderString(str, options, cb); }) diff --git a/lib/hexo/post.js b/lib/hexo/post.js index 032265d77e..956ea7c8c3 100644 --- a/lib/hexo/post.js +++ b/lib/hexo/post.js @@ -13,10 +13,10 @@ const yfm = require('hexo-front-matter'); const preservedKeys = ['title', 'slug', 'path', 'layout', 'date', 'content']; const rPlaceholder = /(?:<|<)!--\uFFFC(\d+)--(?:>|>)/g; -const rSwigVar = /\{\{[\s\S]*?\}\}/g; -const rSwigComment = /\{#[\s\S]*?#\}/g; -const rSwigBlock = /\{%[\s\S]*?%\}/g; -const rSwigFullBlock = /\{% *(.+?)(?: *| +.*?)%\}[\s\S]+?\{% *end\1 *%\}/g; +const rSwigVar = /{{[\s\S]+?}}/g; +const rSwigComment = /{#[\s\S]+?#}/g; +const rSwigBlock = /{%[\s\S]+?%}/g; +const rSwigFullBlock = /{% *(\S+?)(?: *| +.+?)%}[\s\S]+?{% *end\1 *%}/g; const _escapeContent = (cache, str) => { const placeholder = '\uFFFC'; @@ -45,11 +45,10 @@ class PostRenderCache { escapeAllSwigTags(str) { const escape = _str => _escapeContent(this.cache, _str); - return str - .replace(rSwigFullBlock, escape) - .replace(rSwigBlock, escape) - .replace(rSwigComment, '') - .replace(rSwigVar, escape); + return str.replace(rSwigComment, '') // Remove swig comment first to reduce string size being matched next + .replace(rSwigVar, escape) // Escape swig var since it is a simple regexp + .replace(rSwigFullBlock, escape) // swig full block must escaped before swig block to avoid confliction + .replace(rSwigBlock, escape); } }