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
This commit is contained in:
Tobi Lutke
2025-12-31 14:20:36 -04:00
parent c5a44be104
commit 542deb4a21
4 changed files with 11 additions and 27 deletions
+2 -5
View File
@@ -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
+5
View File
@@ -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
+2 -11
View File
@@ -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
+2 -11
View File
@@ -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