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 @@ -84,7 +84,7 @@ class PostRenderEscape {
84
84
* @param {string } str
85
85
* @returns string
86
86
*/
87
- escapeAllSwigTags ( str : string ) {
87
+ escapeAllSwigTags ( str : string , block_swig_tag_map : { [ name : string ] : boolean } ) {
88
88
if ( ! / ( \{ \{ .+ ?\} \} ) | ( \{ # .+ ?# \} ) | ( \{ % .+ ?% \} ) / s. test ( str ) ) {
89
89
return str ;
90
90
}
@@ -158,7 +158,7 @@ class PostRenderEscape {
158
158
buffer = '' ;
159
159
} else if ( char === '%' && next_char === '}' && swig_string_quote === '' ) { // From swig back to plain text
160
160
idx ++ ;
161
- if ( swig_tag_name !== '' && str . includes ( `end ${ swig_tag_name } ` ) ) {
161
+ if ( swig_tag_name !== '' && ( block_swig_tag_map [ swig_tag_name ] ?? false ) ) {
162
162
state = STATE_SWIG_FULL_TAG ;
163
163
swig_start_idx [ state ] = idx ;
164
164
} else {
@@ -518,7 +518,7 @@ class Post {
518
518
data . content = cacheObj . escapeCodeBlocks ( data . content ) ;
519
519
// Escape all Nunjucks/Swig tags
520
520
if ( disableNunjucks === false ) {
521
- data . content = cacheObj . escapeAllSwigTags ( data . content ) ;
521
+ data . content = cacheObj . escapeAllSwigTags ( data . content , tag . block_swig_tag_map ) ;
522
522
}
523
523
524
524
const options : { highlight ?: boolean ; } = data . markdown || { } ;
Original file line number Diff line number Diff line change @@ -1525,6 +1525,36 @@ describe('Post', () => {
1525
1525
data . content . should . contains ( '22222' ) ;
1526
1526
} ) ;
1527
1527
1528
+ it ( 'render() - tag prefix collision during escape swig tag (issue #5635)' , async ( ) => {
1529
+ hexo . extend . tag . register ( 'testtagblock' , ( args , content ) => {
1530
+ return 'rendered_test_tag_block' ;
1531
+ } , { ends : true } ) ;
1532
+ hexo . extend . tag . register ( 'testtag' , args => {
1533
+ return 'rendered_test_tag' ;
1534
+ } ) ;
1535
+
1536
+ const content = [
1537
+ 'x{% testtag name %}' ,
1538
+ '## Title' ,
1539
+ '{% testtagblock %}' ,
1540
+ 'content in block tag' ,
1541
+ '{% endtesttagblock %}'
1542
+ ] . join ( '\n' ) ;
1543
+
1544
+ const data = await post . render ( '' , {
1545
+ content,
1546
+ engine : 'markdown'
1547
+ } ) ;
1548
+
1549
+ hexo . extend . tag . unregister ( 'testtagblock' ) ;
1550
+ hexo . extend . tag . unregister ( 'testtag' ) ;
1551
+
1552
+ data . content . should . contains ( 'rendered_test_tag_block' ) ;
1553
+ data . content . should . contains ( 'rendered_test_tag' ) ;
1554
+ data . content . should . contains ( '<h2' ) ;
1555
+ data . content . should . not . contains ( '## Title' ) ;
1556
+ } ) ;
1557
+
1528
1558
it ( 'render() - incomplete tags throw error' , async ( ) => {
1529
1559
const content = 'nunjucks should throw {# } error' ;
1530
1560
You can’t perform that action at this time.
0 commit comments