diff --git a/app/models/embeddable_host.rb b/app/models/embeddable_host.rb index 6b32dd45bbd..b76a6725b84 100644 --- a/app/models/embeddable_host.rb +++ b/app/models/embeddable_host.rb @@ -1,3 +1,5 @@ +require_dependency 'url_helper' + class EmbeddableHost < ActiveRecord::Base validate :host_must_be_valid belongs_to :category @@ -10,7 +12,7 @@ class EmbeddableHost < ActiveRecord::Base def self.record_for_url(uri) if uri.is_a?(String) - uri = URI(URI.encode(uri)) rescue nil + uri = URI(UrlHelper.escape_uri(uri)) rescue nil end return false unless uri.present? @@ -25,7 +27,10 @@ class EmbeddableHost < ActiveRecord::Base path << "?" << uri.query if uri.query.present? where("lower(host) = ?", host).each do |eh| - return eh if eh.path_whitelist.blank? || !Regexp.new(eh.path_whitelist).match(path).nil? + return eh if eh.path_whitelist.blank? + + path_regexp = Regexp.new(eh.path_whitelist) + return eh if path_regexp.match(path) || path_regexp.match(URI.unescape(path)) end nil @@ -35,7 +40,7 @@ class EmbeddableHost < ActiveRecord::Base # Work around IFRAME reload on WebKit where the referer will be set to the Forum URL return true if url&.starts_with?(Discourse.base_url) - uri = URI(URI.encode(url)) rescue nil + uri = URI(UrlHelper.escape_uri(url)) rescue nil uri.present? && record_for_url(uri).present? end diff --git a/spec/models/embeddable_host_spec.rb b/spec/models/embeddable_host_spec.rb index 2a7f964b533..4d3f5fc9261 100644 --- a/spec/models/embeddable_host_spec.rb +++ b/spec/models/embeddable_host_spec.rb @@ -103,6 +103,22 @@ describe EmbeddableHost do expect(EmbeddableHost.url_allowed?('http://eviltrout.com/rick/smith')).to eq(true) expect(EmbeddableHost.url_allowed?('http://eviltrout.com/morty/sanchez')).to eq(true) end + + it "works with non-english paths" do + Fabricate(:embeddable_host, path_whitelist: '/انگلیسی/.*') + Fabricate(:embeddable_host, path_whitelist: '/definição/.*') + expect(EmbeddableHost.url_allowed?('http://eviltrout.com/انگلیسی/foo')).to eq(true) + expect(EmbeddableHost.url_allowed?('http://eviltrout.com/definição/foo')).to eq(true) + expect(EmbeddableHost.url_allowed?('http://eviltrout.com/bar/foo')).to eq(false) + end + + it "works with URL encoded paths" do + Fabricate(:embeddable_host, path_whitelist: '/definição/.*') + Fabricate(:embeddable_host, path_whitelist: '/ingl%C3%A9s/.*') + + expect(EmbeddableHost.url_allowed?('http://eviltrout.com/defini%C3%A7%C3%A3o/foo')).to eq(true) + expect(EmbeddableHost.url_allowed?('http://eviltrout.com/inglés/foo')).to eq(true) + end end end