@@ -660,6 +660,30 @@ public void BlockPartialWithNestedSpecialNamedPartial2()
660660 Assert . Equal ( "A 1 B 3 C 4 D 2 E" , result ) ;
661661 }
662662
663+ [ Fact ]
664+ public void RecursionUnboundedBlockPartialWithSpecialNamedPartial ( )
665+ {
666+ string source = "{{#>myPartial}}{{>myPartial}}{{/myPartial}}" ;
667+
668+ var template = Handlebars . Compile ( source ) ;
669+
670+ var partialSource = "{{> @partial-block }}" ;
671+ using ( var reader = new StringReader ( partialSource ) )
672+ {
673+ var partialTemplate = Handlebars . Compile ( reader ) ;
674+ Handlebars . RegisterTemplate ( "myPartial" , partialTemplate ) ;
675+ }
676+
677+ string Result ( ) => template ( null ) ;
678+ var ex = Assert . Throws < HandlebarsRuntimeException > ( Result ) ;
679+ Assert . Equal ( "Runtime error while rendering partial 'myPartial', see inner exception for more information" , ex . Message ) ;
680+ ex = Assert . IsType < HandlebarsRuntimeException > ( ex . InnerException ) ;
681+ Assert . Equal ( "Runtime error while rendering partial 'myPartial', see inner exception for more information" , ex . Message ) ;
682+ ex = Assert . IsType < HandlebarsRuntimeException > ( ex . InnerException ) ;
683+ Assert . Equal ( "Referenced partial name @partial-block could not be resolved" , ex . Message ) ;
684+ Assert . Null ( ex . InnerException ) ;
685+ }
686+
663687 [ Fact ]
664688 public void TemplateWithSpecialNamedPartial ( )
665689 {
@@ -717,6 +741,84 @@ public void SubExpressionPartial()
717741 var result = template ( data ) ;
718742 Assert . Equal ( "Hello, world!" , result ) ;
719743 }
744+
745+ [ Fact ]
746+ public void RecursionUnboundedPartial ( )
747+ {
748+ string source = "{{>list}}" ;
749+
750+ var template = Handlebars . Compile ( source ) ;
751+
752+ var partialSource = "{{>list}}" ;
753+ using ( var reader = new StringReader ( partialSource ) )
754+ {
755+ var partialTemplate = Handlebars . Compile ( reader ) ;
756+ Handlebars . RegisterTemplate ( "list" , partialTemplate ) ;
757+ }
758+
759+ string Result ( ) => template ( null ) ;
760+ var ex = Assert . Throws < HandlebarsRuntimeException > ( Result ) ;
761+ while ( ex . InnerException != null )
762+ ex = Assert . IsType < HandlebarsRuntimeException > ( ex . InnerException ) ;
763+ Assert . Equal ( "Runtime error while rendering partial 'list', exceeded recursion depth limit of 100" , ex . Message ) ;
764+ }
765+
766+ [ Fact ]
767+ public void RecursionBoundedToLimitPartial ( )
768+ {
769+ string source = "{{>list}}{{>list}}" ;
770+
771+ var template = Handlebars . Compile ( source ) ;
772+
773+ var partialSource = "x{{#each items}}{{#if items}}{{>list}}{{/if}}{{/each}}" ;
774+ using ( var reader = new StringReader ( partialSource ) )
775+ {
776+ var partialTemplate = Handlebars . Compile ( reader ) ;
777+ Handlebars . RegisterTemplate ( "list" , partialTemplate ) ;
778+ }
779+
780+ var data = new Dictionary < string , object > ( ) ;
781+ var items = data ;
782+ for ( var depth = 0 ; depth < Handlebars . Configuration . PartialRecursionDepthLimit ; depth ++ )
783+ {
784+ var nestedItems = new Dictionary < string , object > ( ) ;
785+ items . Add ( "items" , new [ ] { nestedItems } ) ;
786+ items = nestedItems ;
787+ }
788+
789+ var result = template ( data ) ;
790+ Assert . Equal ( new string ( 'x' , Handlebars . Configuration . PartialRecursionDepthLimit * 2 ) , result ) ;
791+ }
792+
793+ [ Fact ]
794+ public void RecursionBoundedAboveLimitPartial ( )
795+ {
796+ string source = "{{>list}}" ;
797+
798+ var template = Handlebars . Compile ( source ) ;
799+
800+ var partialSource = "x{{#each items}}{{#if items}}{{>list}}{{/if}}{{/each}}" ;
801+ using ( var reader = new StringReader ( partialSource ) )
802+ {
803+ var partialTemplate = Handlebars . Compile ( reader ) ;
804+ Handlebars . RegisterTemplate ( "list" , partialTemplate ) ;
805+ }
806+
807+ var data = new Dictionary < string , object > ( ) ;
808+ var items = data ;
809+ for ( var depth = 0 ; depth < Handlebars . Configuration . PartialRecursionDepthLimit + 1 ; depth ++ )
810+ {
811+ var nestedItems = new Dictionary < string , object > ( ) ;
812+ items . Add ( "items" , new [ ] { nestedItems } ) ;
813+ items = nestedItems ;
814+ }
815+
816+ string Result ( ) => template ( data ) ;
817+ var ex = Assert . Throws < HandlebarsRuntimeException > ( Result ) ;
818+ while ( ex . InnerException != null )
819+ ex = Assert . IsType < HandlebarsRuntimeException > ( ex . InnerException ) ;
820+ Assert . Equal ( "Runtime error while rendering partial 'list', exceeded recursion depth limit of 100" , ex . Message ) ;
821+ }
720822 }
721823}
722824
0 commit comments