File tree Expand file tree Collapse file tree 3 files changed +47
-3
lines changed
Expand file tree Collapse file tree 3 files changed +47
-3
lines changed Original file line number Diff line number Diff line change @@ -206,11 +206,23 @@ type RegisterOptions = {
206206class Tag {
207207 public env : Environment ;
208208 public source : string ;
209+ public block_swig_tag_map : { [ name : string ] : boolean } ;
209210
210211 constructor ( ) {
211212 this . env = new Environment ( null , {
212213 autoescape : false
213214 } ) ;
215+ this . block_swig_tag_map = {
216+ if : true ,
217+ for : true ,
218+ each : true ,
219+ all : true ,
220+ macro : true ,
221+ block : true ,
222+ raw : true ,
223+ filter : true ,
224+ call : true
225+ } ;
214226 }
215227
216228 register ( name : string , fn : TagFunction ) : void
@@ -246,6 +258,7 @@ class Tag {
246258 }
247259
248260 this . env . addExtension ( name , tag ) ;
261+ this . block_swig_tag_map [ name ] = ! ! options . ends ;
249262 }
250263
251264 unregister ( name : string ) : void {
@@ -254,6 +267,7 @@ class Tag {
254267 const { env } = this ;
255268
256269 if ( env . hasExtension ( name ) ) env . removeExtension ( name ) ;
270+ delete this . block_swig_tag_map [ name ] ;
257271 }
258272
259273 render ( str : string ) : Promise < any > ;
Original file line number Diff line number Diff line change @@ -68,7 +68,7 @@ class PostRenderEscape {
6868 * @param {string } str
6969 * @returns string
7070 */
71- escapeAllSwigTags ( str : string ) {
71+ escapeAllSwigTags ( str : string , block_swig_tag_map : { [ name : string ] : boolean } ) {
7272 if ( ! / ( \{ \{ .+ ?\} \} ) | ( \{ # .+ ?# \} ) | ( \{ % .+ ?% \} ) / s. test ( str ) ) {
7373 return str ;
7474 }
@@ -142,7 +142,7 @@ class PostRenderEscape {
142142 buffer = '' ;
143143 } else if ( char === '%' && next_char === '}' && swig_string_quote === '' ) { // From swig back to plain text
144144 idx ++ ;
145- if ( swig_tag_name !== '' && str . includes ( `end ${ swig_tag_name } ` ) ) {
145+ if ( swig_tag_name !== '' && ( block_swig_tag_map [ swig_tag_name ] ?? false ) ) {
146146 state = STATE_SWIG_FULL_TAG ;
147147 swig_start_idx [ state ] = idx ;
148148 } else {
@@ -502,7 +502,7 @@ class Post {
502502 data . content = cacheObj . escapeCodeBlocks ( data . content ) ;
503503 // Escape all Nunjucks/Swig tags
504504 if ( disableNunjucks === false ) {
505- data . content = cacheObj . escapeAllSwigTags ( data . content ) ;
505+ data . content = cacheObj . escapeAllSwigTags ( data . content , tag . block_swig_tag_map ) ;
506506 }
507507
508508 const options : { highlight ?: boolean ; } = data . markdown || { } ;
Original file line number Diff line number Diff line change @@ -1515,6 +1515,36 @@ describe('Post', () => {
15151515 data . content . should . contains ( '22222' ) ;
15161516 } ) ;
15171517
1518+ it ( 'render() - tag prefix collision during escape swig tag (issue #5635)' , async ( ) => {
1519+ hexo . extend . tag . register ( 'testtagblock' , ( args , content ) => {
1520+ return 'rendered_test_tag_block' ;
1521+ } , { ends : true } ) ;
1522+ hexo . extend . tag . register ( 'testtag' , args => {
1523+ return 'rendered_test_tag' ;
1524+ } ) ;
1525+
1526+ const content = [
1527+ 'x{% testtag name %}' ,
1528+ '## Title' ,
1529+ '{% testtagblock %}' ,
1530+ 'content in block tag' ,
1531+ '{% endtesttagblock %}'
1532+ ] . join ( '\n' ) ;
1533+
1534+ const data = await post . render ( '' , {
1535+ content,
1536+ engine : 'markdown'
1537+ } ) ;
1538+
1539+ hexo . extend . tag . unregister ( 'testtagblock' ) ;
1540+ hexo . extend . tag . unregister ( 'testtag' ) ;
1541+
1542+ data . content . should . contains ( 'rendered_test_tag_block' ) ;
1543+ data . content . should . contains ( 'rendered_test_tag' ) ;
1544+ data . content . should . contains ( '<h2' ) ;
1545+ data . content . should . not . contains ( '## Title' ) ;
1546+ } ) ;
1547+
15181548 it ( 'render() - incomplete tags throw error' , async ( ) => {
15191549 const content = 'nunjucks should throw {# } error' ;
15201550
You can’t perform that action at this time.
0 commit comments