From 2a4d33e61515edb6be1cf299ddea42f4c5b8d56d Mon Sep 17 00:00:00 2001 From: ashmaroli Date: Thu, 15 Jun 2017 00:36:55 +0530 Subject: [PATCH] patch URLFilters to prevent `//` (#6058) Merge pull request 6058 --- lib/jekyll/filters/url_filters.rb | 15 +++++++++---- test/test_filters.rb | 36 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/jekyll/filters/url_filters.rb b/lib/jekyll/filters/url_filters.rb index 7db83c80..40cacc22 100644 --- a/lib/jekyll/filters/url_filters.rb +++ b/lib/jekyll/filters/url_filters.rb @@ -11,7 +11,6 @@ module Jekyll def absolute_url(input) return if input.nil? return input if Addressable::URI.parse(input).absolute? - site = @context.registers[:site] return relative_url(input).to_s if site.config["url"].nil? Addressable::URI.parse(site.config["url"] + relative_url(input)).normalize.to_s end @@ -23,14 +22,22 @@ module Jekyll # Returns a URL relative to the domain root as a String. def relative_url(input) return if input.nil? - site = @context.registers[:site] - return ensure_leading_slash(input.to_s) if site.config["baseurl"].nil? + return ensure_leading_slash(input.to_s) if sanitized_baseurl.nil? Addressable::URI.parse( - ensure_leading_slash(site.config["baseurl"]) + ensure_leading_slash(input.to_s) + ensure_leading_slash(sanitized_baseurl) + ensure_leading_slash(input.to_s) ).normalize.to_s end private + + def site + @context.registers[:site] + end + + def sanitized_baseurl + site.config["baseurl"].chomp("/") + end + def ensure_leading_slash(input) return input if input.nil? || input.empty? || input.start_with?("/") "/#{input}" diff --git a/test/test_filters.rb b/test/test_filters.rb index 03d2732a..76da6042 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -394,6 +394,15 @@ class TestFilters < JekyllUnitTest assert_equal "http://example.com/", filter.absolute_url(page_url) end + should "not append a forward slash if both input and baseurl are simply '/'" do + page_url = "/" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "/", + }) + assert_equal "http://example.com/", filter.absolute_url(page_url) + end + should "normalize international URLs" do page_url = "" filter = make_filter_mock({ @@ -448,6 +457,33 @@ class TestFilters < JekyllUnitTest }) assert_equal "/base", filter.relative_url(page_url) end + + should "not prepend a forward slash if baseurl ends with a single '/'" do + page_url = "/css/main.css" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "/base/", + }) + assert_equal "/base/css/main.css", filter.relative_url(page_url) + end + + should "not return valid URI if baseurl ends with multiple '/'" do + page_url = "/css/main.css" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "/base//", + }) + refute_equal "/base/css/main.css", filter.relative_url(page_url) + end + + should "not prepend a forward slash if both input and baseurl are simply '/'" do + page_url = "/" + filter = make_filter_mock({ + "url" => "http://example.com", + "baseurl" => "/", + }) + assert_equal "/", filter.relative_url(page_url) + end end context "jsonify filter" do