From 542deb4a21522a979960fcd7dd827d3c3a034749 Mon Sep 17 00:00:00 2001 From: Tobi Lutke Date: Wed, 31 Dec 2025 14:20:36 -0400 Subject: [PATCH] Fix compiled template external calls - Don't undef __send__ (causes warnings) - Dynamic include/render now call __external__.call(:include/render, ...) - Default external handler raises FileSystemError for missing assets - Enables proper yield-based external call handling --- lib/liquid/box.rb | 7 ++----- lib/liquid/compile/compiled_template.rb | 5 +++++ lib/liquid/compile/tags/include_compiler.rb | 13 ++----------- lib/liquid/compile/tags/render_compiler.rb | 13 ++----------- 4 files changed, 11 insertions(+), 27 deletions(-) diff --git a/lib/liquid/box.rb b/lib/liquid/box.rb index 43ec57ea..2cef5de6 100644 --- a/lib/liquid/box.rb +++ b/lib/liquid/box.rb @@ -386,16 +386,13 @@ module Liquid end def neuter_basic_object! - # Suppress the "__send__" warning - we know what we're doing @box.eval(<<~'RUBY') - original_verbose = $VERBOSE - $VERBOSE = nil class BasicObject undef_method(:instance_eval) rescue nil undef_method(:instance_exec) rescue nil - undef_method(:__send__) rescue nil + # Don't undef __send__ - it causes warnings and is equivalent to send + # which we already restrict via public_send end - $VERBOSE = original_verbose RUBY end diff --git a/lib/liquid/compile/compiled_template.rb b/lib/liquid/compile/compiled_template.rb index db09525a..d646e1c7 100644 --- a/lib/liquid/compile/compiled_template.rb +++ b/lib/liquid/compile/compiled_template.rb @@ -173,6 +173,11 @@ module Liquid input # Return unchanged if filter not found end + when :include, :render + # Dynamic include/render - not supported without a custom handler + template_name, _var, _attrs, _alias_name, *_rest = args + raise Liquid::FileSystemError, "Could not find asset #{template_name}" + else raise ArgumentError, "Unknown external call type: #{call_type}" end diff --git a/lib/liquid/compile/tags/include_compiler.rb b/lib/liquid/compile/tags/include_compiler.rb index 22151591..567c667b 100644 --- a/lib/liquid/compile/tags/include_compiler.rb +++ b/lib/liquid/compile/tags/include_compiler.rb @@ -95,7 +95,6 @@ module Liquid if compiler.debug? code.line "# Dynamic include (template name from variable)" - code.line "$stderr.puts '* WARN: Liquid runtime file system access - dynamic include (template name from variable)' if $VERBOSE" end name_expr = ExpressionCompiler.compile(template_name_expr, compiler) @@ -111,16 +110,8 @@ module Liquid var_expr = variable_name_expr ? ExpressionCompiler.compile(variable_name_expr, compiler) : "nil" alias_expr = alias_name ? alias_name.inspect : "nil" - # Call the runtime dynamic include method - code.line "if defined?(__include_dynamic__)" - code.indent do - code.line "__output__ << __include_dynamic__(#{name_expr}, #{var_expr}, #{attrs_var}, #{alias_expr}, assigns)" - end - code.line "else" - code.indent do - code.line "raise RuntimeError, 'Dynamic include requires __include_dynamic__ method: ' + #{name_expr}.inspect" - end - code.line "end" + # Call the external handler for dynamic includes + code.line "__output__ << __external__.call(:include, #{name_expr}, #{var_expr}, #{attrs_var}, #{alias_expr}, assigns, __context__)" end end end diff --git a/lib/liquid/compile/tags/render_compiler.rb b/lib/liquid/compile/tags/render_compiler.rb index ac778d0f..3cf85766 100644 --- a/lib/liquid/compile/tags/render_compiler.rb +++ b/lib/liquid/compile/tags/render_compiler.rb @@ -152,7 +152,6 @@ module Liquid if compiler.debug? code.line "# Dynamic render (template name from variable)" - code.line "$stderr.puts '* WARN: Liquid runtime file system access - dynamic render (template name from variable)' if $VERBOSE" end name_expr = ExpressionCompiler.compile(template_name_expr, compiler) @@ -168,16 +167,8 @@ module Liquid var_expr = variable_name_expr ? ExpressionCompiler.compile(variable_name_expr, compiler) : "nil" alias_expr = alias_name ? alias_name.inspect : "nil" - # Call the runtime dynamic render method - code.line "if defined?(__render_dynamic__)" - code.indent do - code.line "__output__ << __render_dynamic__(#{name_expr}, #{var_expr}, #{attrs_var}, #{alias_expr}, #{is_for_loop})" - end - code.line "else" - code.indent do - code.line "raise RuntimeError, 'Dynamic render requires __render_dynamic__ method: ' + #{name_expr}.inspect" - end - code.line "end" + # Call the external handler for dynamic renders + code.line "__output__ << __external__.call(:render, #{name_expr}, #{var_expr}, #{attrs_var}, #{alias_expr}, #{is_for_loop}, __context__)" end end end