File tree 3 files changed +47
-3
lines changed 3 files changed +47
-3
lines changed Original file line number Diff line number Diff line change @@ -206,11 +206,23 @@ type RegisterOptions = {
206
206
class Tag {
207
207
public env : Environment ;
208
208
public source : string ;
209
+ public block_swig_tag_map : { [ name : string ] : boolean } ;
209
210
210
211
constructor ( ) {
211
212
this . env = new Environment ( null , {
212
213
autoescape : false
213
214
} ) ;
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
+ } ;
214
226
}
215
227
216
228
register ( name : string , fn : TagFunction ) : void
@@ -246,6 +258,7 @@ class Tag {
246
258
}
247
259
248
260
this . env . addExtension ( name , tag ) ;
261
+ this . block_swig_tag_map [ name ] = ! ! options . ends ;
249
262
}
250
263
251
264
unregister ( name : string ) : void {
@@ -254,6 +267,7 @@ class Tag {
254
267
const { env } = this ;
255
268
256
269
if ( env . hasExtension ( name ) ) env . removeExtension ( name ) ;
270
+ delete this . block_swig_tag_map [ name ] ;
257
271
}
258
272
259
273
render ( str : string ) : Promise < any > ;
Original file line number Diff line number Diff line change @@ -68,7 +68,7 @@ class PostRenderEscape {
68
68
* @param {string } str
69
69
* @returns string
70
70
*/
71
- escapeAllSwigTags ( str : string ) {
71
+ escapeAllSwigTags ( str : string , block_swig_tag_map : { [ name : string ] : boolean } ) {
72
72
if ( ! / ( \{ \{ .+ ?\} \} ) | ( \{ # .+ ?# \} ) | ( \{ % .+ ?% \} ) / s. test ( str ) ) {
73
73
return str ;
74
74
}
@@ -142,7 +142,7 @@ class PostRenderEscape {
142
142
buffer = '' ;
143
143
} else if ( char === '%' && next_char === '}' && swig_string_quote === '' ) { // From swig back to plain text
144
144
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 ) ) {
146
146
state = STATE_SWIG_FULL_TAG ;
147
147
swig_start_idx [ state ] = idx ;
148
148
} else {
@@ -502,7 +502,7 @@ class Post {
502
502
data . content = cacheObj . escapeCodeBlocks ( data . content ) ;
503
503
// Escape all Nunjucks/Swig tags
504
504
if ( disableNunjucks === false ) {
505
- data . content = cacheObj . escapeAllSwigTags ( data . content ) ;
505
+ data . content = cacheObj . escapeAllSwigTags ( data . content , tag . block_swig_tag_map ) ;
506
506
}
507
507
508
508
const options : { highlight ?: boolean ; } = data . markdown || { } ;
Original file line number Diff line number Diff line change @@ -1515,6 +1515,36 @@ describe('Post', () => {
1515
1515
data . content . should . contains ( '22222' ) ;
1516
1516
} ) ;
1517
1517
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
+
1518
1548
it ( 'render() - incomplete tags throw error' , async ( ) => {
1519
1549
const content = 'nunjucks should throw {# } error' ;
1520
1550
You can’t perform that action at this time.
0 commit comments