diff --git a/Gemfile b/Gemfile
index 55b79268c..e4178086a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -17,7 +17,7 @@ gem "delayed_job_active_record"
gem "simple_form"
gem "mechanize"
gem "whenever", :require => false
-gem "sanitize", "~> 3.1.0"
+gem "sanitize"
gem 'rmagick'
gem 'net-sftp'
gem 'term-ansicolor', :require => "term/ansicolor"
@@ -44,6 +44,7 @@ gem 'memoist'
gem 'daemons'
gem 'oauth2'
gem 'bootsnap'
+gem 'addressable'
# needed for looser jpeg header compat
gem 'ruby-imagespec', :require => "image_spec", :git => "https://github.com/r888888888/ruby-imagespec.git", :branch => "exif-fixes"
diff --git a/Gemfile.lock b/Gemfile.lock
index ada2548ef..45f0286b8 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -199,7 +199,7 @@ GEM
metaclass (0.0.4)
method_source (0.8.2)
mime-types (2.99.3)
- mini_portile2 (2.1.0)
+ mini_portile2 (2.2.0)
minitest (5.10.1)
mocha (1.2.1)
metaclass (~> 0.0.1)
@@ -218,11 +218,11 @@ GEM
net-ssh (2.9.2)
netrc (0.10.3)
newrelic_rpm (3.13.0.299)
- nokogiri (1.7.0.1)
- mini_portile2 (~> 2.1.0)
- nokogiri (1.7.0.1-x64-mingw32)
- mini_portile2 (~> 2.1.0)
- nokogumbo (1.2.0)
+ nokogiri (1.8.0)
+ mini_portile2 (~> 2.2.0)
+ nokogiri (1.8.0-x64-mingw32)
+ mini_portile2 (~> 2.2.0)
+ nokogumbo (1.4.13)
nokogiri
ntlm-http (0.1.1)
oauth2 (1.3.0)
@@ -292,10 +292,10 @@ GEM
rmagick (2.16.0)
ruby-prof (0.15.8)
rubyzip (1.1.7)
- sanitize (3.1.2)
- crass (~> 1.0.1)
+ sanitize (4.5.0)
+ crass (~> 1.0.2)
nokogiri (>= 1.4.4)
- nokogumbo (= 1.2.0)
+ nokogumbo (~> 1.4.1)
sass (3.4.23)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
@@ -387,6 +387,7 @@ PLATFORMS
x64-mingw32
DEPENDENCIES
+ addressable
awesome_print
aws-sdk (~> 2)
bcrypt-ruby
@@ -429,7 +430,7 @@ DEPENDENCIES
ruby-imagespec!
ruby-prof
rubyzip
- sanitize (~> 3.1.0)
+ sanitize
sass-rails
shoulda-context
shoulda-matchers
diff --git a/app/logical/note_sanitizer.rb b/app/logical/note_sanitizer.rb
index 27ca58345..9fa18cf3c 100644
--- a/app/logical/note_sanitizer.rb
+++ b/app/logical/note_sanitizer.rb
@@ -73,7 +73,20 @@ module NoteSanitizer
at_rules: [],
protocols: [],
properties: ALLOWED_PROPERTIES,
- }
+ },
+ :transformers => method(:relativize_links),
)
end
+
+ def self.relativize_links(node:, **env)
+ return unless node.name == "a" && node.attribute("href")
+
+ href = node.attribute("href")
+ url = Addressable::URI.parse(href.value).normalize
+
+ if url.authority.in?(Danbooru.config.hostnames)
+ url.site = nil
+ href.value = url.to_s
+ end
+ end
end
diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb
index 662f79b71..bac24967e 100644
--- a/config/danbooru_default_config.rb
+++ b/config/danbooru_default_config.rb
@@ -20,11 +20,17 @@ module Danbooru
"Find good anime art fast"
end
- # The hostname of the server.
+ # The canonical hostname of the site.
def hostname
Socket.gethostname
end
+ # The list of all domain names this site is accessible under.
+ # Example: %w[danbooru.donmai.us sonohara.donmai.us hijiribe.donmai.us safebooru.donmai.us]
+ def hostnames
+ [hostname]
+ end
+
# Contact email address of the admin.
def contact_email
"webmaster@#{server_host}"
diff --git a/test/unit/note_sanitizer_test.rb b/test/unit/note_sanitizer_test.rb
index e87ed67d7..bebacb3ae 100644
--- a/test/unit/note_sanitizer_test.rb
+++ b/test/unit/note_sanitizer_test.rb
@@ -21,5 +21,12 @@ class NoteSanitizerTest < ActiveSupport::TestCase
body = 'google'
assert_equal('google', NoteSanitizer.sanitize(body))
end
+
+ should "rewrite absolute links to relative links" do
+ Danbooru.config.stubs(:hostnames).returns(%w[danbooru.donmai.us sonohara.donmai.us hijiribe.donmai.us])
+
+ body = 'touhou'
+ assert_equal('touhou', NoteSanitizer.sanitize(body))
+ end
end
end