Sanitize tag urls (#13720)

* Sanitize tag URLs

For tags with non-ASCII names, we were generating busted URLs, which
would then cause errors. This commit fixes that particular error by
generating usable URLs.

* Use URL generator that will sanitize tag names

* Remove path prefix when using a URL generator
This commit is contained in:
Jamie Gaskins 2021-05-11 11:21:03 -04:00 committed by GitHub
parent 111b7316d9
commit bcc42a130d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 14 additions and 7 deletions

View file

@ -46,7 +46,7 @@ module URL
#
# @param tag [Tag] the tag to create the URL for
def self.tag(tag, page = 1)
url(["/t/#{tag.name}", ("/page/#{page}" if page > 1)].join)
url(["/t/#{CGI.escape(tag.name)}", ("/page/#{page}" if page > 1)].join)
end
# Creates a user URL

View file

@ -5,7 +5,7 @@
</div>
<div class="ml-auto">
<a href="<%= tag_path(@tag.name) %>" class="crayons-btn crayons-btn--outlined" target="_blank" rel="noopener noreferer">View</a>
<a href="<%= URL.tag(@tag) %>" class="crayons-btn crayons-btn--outlined" target="_blank" rel="noopener noreferer">View</a>
</div>
</header>

View file

@ -59,7 +59,7 @@
<div class="crayons-story__tags">
<% flare_tag = FlareTag.new(story, @tag).tag %>
<% if flare_tag %>
<a href="/t/<%= flare_tag.name %>" class="crayons-tag" style="background:<%= flare_tag.bg_color_hex %>;color:<%= flare_tag.text_color_hex %>"><span class="crayons-tag__prefix">#</span><%= flare_tag.name %></a>
<a href="<%= URL.tag flare_tag.name %>" class="crayons-tag" style="background:<%= flare_tag.bg_color_hex %>;color:<%= flare_tag.text_color_hex %>"><span class="crayons-tag__prefix">#</span><%= flare_tag.name %></a>
<% end %>
<% tags_to_display = story.cached_tag_list_array
if flare_tag

View file

@ -30,7 +30,7 @@
<% color = Color::CompareHex.new([tag.bg_color_hex || "#0000000", tag.text_color_hex || "#ffffff"]).brightness(0.8) %>
<div class="crayons-card branded-2 p-4 m:p-6 m:pt-4 flex flex-col single-article break-word content-center <% if follow.explicit_points < 0 %>opacity-75<% end %>" style="border-top-color: <%= color %>;" id="follows-<%= follow.id %>">
<h3 class="s:mb-1 -ml-1 p-0 fw-medium">
<a href="/t/<%= tag.name %>" class="crayons-tag crayons-tag--l">
<a href="<%= URL.tag tag %>" class="crayons-tag crayons-tag--l">
<span class="crayons-tag__prefix">#</span><%= tag.name %>
</a>
<% if follow.explicit_points < 0 %>

View file

@ -7,7 +7,7 @@
}
</style>
<div class="ltag__tag__content">
<h2>#<a href="/t/<%= tag.name %>" class="ltag__tag__link"><%= tag.name %></a> <%= follow_btn %></h2>
<h2>#<a href="<%= URL.tag tag %>" class="ltag__tag__link"><%= tag.name %></a> <%= follow_btn %></h2>
<div class="ltag__tag__summary">
<%= tag.short_summary %>
</div>

View file

@ -21,7 +21,7 @@
<div class="slanty-accent"></div>
<div class="tag-or-query-header-container tag-edit-tag">
<h1> Editing:
<a href="/t/<%= @tag.name %>" style="color: <%= @tag.text_color_hex %>;text-decoration: underline;"><%= @tag.name %></a>
<a href="<%= URL.tag @tag %>" style="color: <%= @tag.text_color_hex %>;text-decoration: underline;"><%= @tag.name %></a>
</h1>
<p>
<code style="background-color: #D2D2D2; color: black; padding: 5px; border-radius: 5px;">#<%= @tag.name %></code> is the name of the tag used in Markdown.

View file

@ -29,7 +29,7 @@
<% color = Color::CompareHex.new([tag.bg_color_hex || "#0000000", tag.text_color_hex || "#ffffff"]).brightness(0.8) %>
<div class="tag-card crayons-card branded-4 p-4 m:p-6 m:pt-4 flex flex-col relative" style="border-top-color: <%= color %>; ">
<h3 class="crayons-tag crayons-tag--l mb-2">
<a href="/t/<%= tag.name %>" class="crayons-link">
<a href="<%= URL.tag tag %>" class="crayons-link">
<span class="crayons-tag__prefix">#</span><%= tag.name %>
</a>
</h3>

View file

@ -94,6 +94,13 @@ RSpec.describe URL, type: :lib do
it "returns the correct URL for a tag" do
expect(described_class.tag(tag, 2)).to eq("https://dev.to/t/#{tag.name}/page/2")
end
it "returns the correct URL for a tag with a non-ASCII name" do
# Due to validations we can't trivially create a tag with a non-ASCII name
# so we just create something that quacks like one.
tag = instance_double("Tag", name: "histórico")
expect(described_class.tag(tag)).to eq("https://dev.to/t/hist%C3%B3rico")
end
end
describe ".deep_link" do