`rel="me"` check should be case-insenstive (#32238)

pull/26649/merge
Christian Schmidt 2024-11-21 15:37:25 +01:00 committed by GitHub
parent dbddd40c1c
commit 7385016837
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 30 additions and 3 deletions

View File

@ -237,7 +237,7 @@ class LinkDetailsExtractor
end end
def link_tag(name) def link_tag(name)
document.xpath("//link[@rel=\"#{name}\"]").pick('href') document.xpath("//link[nokogiri:link_rel_include(@rel, '#{name}')]", NokogiriHandler).pick('href')
end end
def opengraph_tag(name) def opengraph_tag(name)

View File

@ -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

View File

@ -74,7 +74,7 @@ class FetchResourceService < BaseService
def process_html(response) def process_html(response)
page = Nokogiri::HTML5(response.body_with_limit) 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? process(json_link['href'], terminal: true) unless json_link.nil?
end end

View File

@ -26,7 +26,7 @@ class VerifyLinkService < BaseService
def link_back_present? def link_back_present?
return false if @body.blank? 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 } if links.any? { |link| link['href']&.downcase == @link_back.downcase }
true true

View File

@ -46,6 +46,21 @@ RSpec.describe VerifyLinkService do
end end
end end
context 'when a link contains an <a rel=ME> back' do
let(:html) do
<<~HTML
<!doctype html>
<body>
<a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel=ME>Follow me on Mastodon</a>
</body>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
context 'when a link contains a <link> back' do context 'when a link contains a <link> back' do
let(:html) do let(:html) do
<<~HTML <<~HTML