change: Render an opaque internal error by default for non-Liquid::Error (#835)

These errors may contain sensitive information, so is safer to
render a more vague message by default.

This is done by replacing non-Liquid::Error exceptions with a
Liquid::InternalError exception with the non-Liquid::Error accessible on
through the cause method. This also allows the template name and line
number to be attached to the template errors.

The exception_handler render option has been changed to exception_renderer
since now it should raise an exception to re-raise on a liquid rendering
error or return a string to be rendered where the error occurred.
This commit is contained in:
Dylan Thacker-Smith
2016-12-07 17:34:29 -05:00
committed by GitHub
parent a9b84b7806
commit f27bd619b9
6 changed files with 45 additions and 55 deletions
+15 -27
View File
@@ -13,7 +13,7 @@ module Liquid
# context['bob'] #=> nil class Context
class Context
attr_reader :scopes, :errors, :registers, :environments, :resource_limits
attr_accessor :exception_handler, :template_name, :partial, :global_filter, :strict_variables, :strict_filters
attr_accessor :exception_renderer, :template_name, :partial, :global_filter, :strict_variables, :strict_filters
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil)
@environments = [environments].flatten
@@ -28,7 +28,7 @@ module Liquid
@this_stack_used = false
if rethrow_errors
self.exception_handler = ->(e) { raise }
self.exception_renderer = ->(e) { raise }
end
@interrupts = []
@@ -74,32 +74,13 @@ module Liquid
end
def handle_error(e, line_number = nil, raw_token = nil)
if e.is_a?(Liquid::Error)
e.template_name ||= template_name
e.line_number ||= line_number
end
output = nil
if exception_handler
args = [e]
args << { line_number: line_number, raw_token: raw_token } if exception_handler.arity == 2
result = exception_handler.call(*args)
case result
when Exception
e = result
if e.is_a?(Liquid::Error)
e.template_name ||= template_name
e.line_number ||= line_number
end
when String
output = result
else
raise if result
end
end
e = internal_error unless e.is_a?(Liquid::Error)
e.template_name ||= template_name
e.line_number ||= line_number
errors.push(e)
output || Liquid::Error.render(e)
e = exception_renderer.call(e) if exception_renderer
e.to_s
end
def invoke(method, *args)
@@ -223,6 +204,13 @@ module Liquid
private
def internal_error
# raise and catch to set backtrace and cause on exception
raise Liquid::InternalError, 'internal'
rescue Liquid::InternalError => exc
exc
end
def squash_instance_assigns_with_environments
@scopes.last.each_key do |k|
@environments.each do |env|