diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb
index e4e815c38d..56533f6553 100644
--- a/app/lib/link_details_extractor.rb
+++ b/app/lib/link_details_extractor.rb
@@ -237,7 +237,7 @@ class LinkDetailsExtractor
end
def link_tag(name)
- document.xpath("//link[@rel=\"#{name}\"]").pick('href')
+ document.xpath("//link[nokogiri:link_rel_include(@rel, '#{name}')]", NokogiriHandler).pick('href')
end
def opengraph_tag(name)
diff --git a/app/lib/nokogiri_handler.rb b/app/lib/nokogiri_handler.rb
new file mode 100644
index 0000000000..804bcb9c04
--- /dev/null
+++ b/app/lib/nokogiri_handler.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class NokogiriHandler
+ class << self
+ # See "set of space-separated tokens" in the HTML5 spec.
+ WHITE_SPACE = /[ \x09\x0A\x0C\x0D]+/
+
+ def link_rel_include(token_list, token)
+ token_list.to_s.downcase.split(WHITE_SPACE).include?(token.downcase)
+ end
+ end
+end
diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb
index 911950ccca..3fde78455c 100644
--- a/app/services/fetch_resource_service.rb
+++ b/app/services/fetch_resource_service.rb
@@ -74,7 +74,7 @@ class FetchResourceService < BaseService
def process_html(response)
page = Nokogiri::HTML5(response.body_with_limit)
- json_link = page.xpath('//link[@rel="alternate"]').find { |link| ACTIVITY_STREAM_LINK_TYPES.include?(link['type']) }
+ json_link = page.xpath('//link[nokogiri:link_rel_include(@rel, "alternate")]', NokogiriHandler).find { |link| ACTIVITY_STREAM_LINK_TYPES.include?(link['type']) }
process(json_link['href'], terminal: true) unless json_link.nil?
end
diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb
index 17c86426be..fc3c4cbc28 100644
--- a/app/services/verify_link_service.rb
+++ b/app/services/verify_link_service.rb
@@ -26,7 +26,7 @@ class VerifyLinkService < BaseService
def link_back_present?
return false if @body.blank?
- links = Nokogiri::HTML5(@body).css("a[rel~='me'],link[rel~='me']")
+ links = Nokogiri::HTML5(@body).xpath('(//a|//link)[@rel][nokogiri:link_rel_include(@rel, "me")]', NokogiriHandler)
if links.any? { |link| link['href']&.downcase == @link_back.downcase }
true
diff --git a/spec/services/verify_link_service_spec.rb b/spec/services/verify_link_service_spec.rb
index a4fd19751b..7e2f9607cf 100644
--- a/spec/services/verify_link_service_spec.rb
+++ b/spec/services/verify_link_service_spec.rb
@@ -46,6 +46,21 @@ RSpec.describe VerifyLinkService do
end
end
+ context 'when a link contains an back' do
+ let(:html) do
+ <<~HTML
+
+
+ Follow me on Mastodon
+
+ HTML
+ end
+
+ it 'marks the field as verified' do
+ expect(field.verified?).to be true
+ end
+ end
+
context 'when a link contains a back' do
let(:html) do
<<~HTML