discourse/lib/onebox/normalizer.rb
Loïc Guitaut caaa8f9c9e
FIX: Don't escape HTML entities twice in oneboxes (#37141)
Sometimes, HTML entities can be escaped twice, typically when getting
sanitized data from our `Onebox::OpenGraph` class then providing that
value to a template. We’re using the Mustache gem to process the Onebox
templates, and it will automatically escape HTML entities. This is
usually not a problem, but it is for things like ampersands. For
example, if the value we provide to the template is `&`, then
Mustache will convert it to `&`.

This patch fixes that behavior by decoding the result of the sanitization
we apply in `Onebox::OpenGraph`. That way, templates will get `&`
instead of `&`, thus there won’t be any double escaping.
2026-01-16 11:40:18 +01:00

55 lines
1.2 KiB
Ruby

# frozen_string_literal: true
module Onebox
class Normalizer
attr_reader :data
def get(attr, *args)
value = data[attr]
return if value.blank?
return value.map { |v| sanitize_value(v, *args) } if value.is_a?(Array)
sanitize_value(value, *args)
end
private
def method_missing(attr, *args, &block)
value = get(attr, *args)
return nil if value.blank?
method_name = attr.to_s
if method_name.end_with?(*integer_suffixes)
value.to_i
elsif method_name.end_with?(*url_suffixes)
Onebox::Helpers.normalize_url_for_output(value).presence
else
value
end
end
def respond_to_missing?(attr, include_private = false)
data.key?(attr) || super
end
def sanitize_value(value, length = nil, sanitize = true)
value = html_entities.decode(value)
value = html_entities.decode(Sanitize.fragment(value)) if sanitize
value.strip!
value = Onebox::Helpers.truncate(value, length) if length
value
end
def integer_suffixes
%w[width height]
end
def url_suffixes
%w[url image video]
end
def html_entities
@html_entities ||= HTMLEntities.new
end
end
end