From 2e980f3534b680fbd79d7ec39552b4afb7675d6c Mon Sep 17 00:00:00 2001 From: Slevin Date: Tue, 31 Aug 2021 11:57:18 +0800 Subject: [PATCH] Fix memory leaks for proc template (#1719) Fix memory leaks for proc template --- lib/sinatra/base.rb | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index e28ea022fd..92887ed167 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -869,12 +869,12 @@ def render(engine, data, options = {}, locals = {}, &block) def compile_template(engine, data, options, views) eat_errors = options.delete :eat_errors - template_cache.fetch engine, data, options, views do - template = Tilt[engine] - raise "Template engine not found: #{engine}" if template.nil? + template = Tilt[engine] + raise "Template engine not found: #{engine}" if template.nil? - case data - when Symbol + case data + when Symbol + template_cache.fetch engine, data, options, views do body, path, line = settings.templates[data] if body body = body.call if body.respond_to?(:call) @@ -892,17 +892,24 @@ def compile_template(engine, data, options, views) throw :layout_missing if eat_errors and not found template.new(path, 1, options) end - when Proc, String - body = data.is_a?(String) ? Proc.new { data } : data - caller = settings.caller_locations.first - path = options[:path] || caller[0] - line = options[:line] || caller[1] - template.new(path, line.to_i, options, &body) - else - raise ArgumentError, "Sorry, don't know how to render #{data.inspect}." end + when Proc + compile_block_template(template, options, &data) + when String + template_cache.fetch engine, data, options, views do + compile_block_template(template, options) { data } + end + else + raise ArgumentError, "Sorry, don't know how to render #{data.inspect}." end end + + def compile_block_template(template, options, &body) + caller = settings.caller_locations.first + path = options[:path] || caller[0] + line = options[:line] || caller[1] + template.new(path, line.to_i, options, &body) + end end # Base class for all Sinatra applications and middleware.