mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-09-13 12:02:03 +09:00
Read a preview's host as a name by its last label
A domain name ends in a word, which is what keeps it from reading as an address. "0x7f.0.0.1" carries a dot and a letter, so the previous shape check let it through while a browser fetched 127.0.0.1. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186eyzivcTn6wqjEE4Wnxdt
This commit is contained in:
@@ -48,11 +48,17 @@ class ActionText::Attachment::OpengraphEmbed
|
||||
end
|
||||
|
||||
# A preview names a page on the public internet, so its host is a domain
|
||||
# name: it has a dot and a letter in it, and no escapes. A bare address is
|
||||
# not one, and a browser rewrites the many spellings of an address into a
|
||||
# name, written plainly. A bare address is not one, and a browser rewrites
|
||||
# the many spellings of an address ("2130706433", "0x7f.0.0.1") into a
|
||||
# single one before it fetches, which is a race a comparison here loses.
|
||||
def named_host?(host)
|
||||
host.present? && host.exclude?("%") && host.include?(".") && host.match?(/[a-z]/i)
|
||||
host.present? && host.exclude?("%") && host.include?(".") && domain_ending?(host.split(".").last)
|
||||
end
|
||||
|
||||
# What keeps a name from reading as an address is its last label, which is
|
||||
# a word: never a number, and never the hexadecimal spelling of one.
|
||||
def domain_ending?(label)
|
||||
label.match?(/[a-z]/i) && !label.match?(/\A0x/i)
|
||||
end
|
||||
|
||||
def canonical_host(host)
|
||||
|
||||
@@ -38,7 +38,8 @@ class ActionText::Attachment::OpengraphEmbedTest < ActiveSupport::TestCase
|
||||
|
||||
test "drops a link and an image on a bare address rather than a domain name" do
|
||||
[ "http://127.0.0.1/rooms/1", "http://2130706433/rooms/1", "http://0177.0.0.1/rooms/1",
|
||||
"http://[::1]/rooms/1", "http://localhost/rooms/1", "https://203.0.113.10/image.png" ].each do |value|
|
||||
"http://0x7f.0.0.1/rooms/1", "http://1.2.3.0xff/rooms/1", "http://[::1]/rooms/1",
|
||||
"http://localhost/rooms/1", "https://203.0.113.10/image.png" ].each do |value|
|
||||
embed = embed_from href: value, url: value
|
||||
|
||||
assert_nil embed.href, "expected #{value.inspect} to be dropped as a link"
|
||||
@@ -46,6 +47,13 @@ class ActionText::Attachment::OpengraphEmbedTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
test "keeps an internationalized domain written in punycode" do
|
||||
embed = embed_from href: "https://xn--80aswg.xn--p1ai/page", url: "https://xn--80aswg.xn--p1ai/image.png"
|
||||
|
||||
assert_equal "https://xn--80aswg.xn--p1ai/page", embed.href
|
||||
assert_equal "https://xn--80aswg.xn--p1ai/image.png", embed.url
|
||||
end
|
||||
|
||||
test "renders the image and the link when both are web URLs" do
|
||||
html = render_embed href: "https://example.com/page", url: "https://example.com/image.png"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user