From 48e6cb18d700535b01b78c55c9d268307673a7bd Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Sat, 9 May 2020 16:59:13 +0530 Subject: [PATCH] Improve path normalization in liquid_renderer (#8075) Merge pull request 8075 --- lib/jekyll/liquid_renderer.rb | 33 ++++++++++++++++++--------------- lib/jekyll/theme.rb | 5 +++++ test/test_liquid_renderer.rb | 28 ++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/lib/jekyll/liquid_renderer.rb b/lib/jekyll/liquid_renderer.rb index 33df9d3c351..7655e04da2e 100644 --- a/lib/jekyll/liquid_renderer.rb +++ b/lib/jekyll/liquid_renderer.rb @@ -5,11 +5,6 @@ module Jekyll class LiquidRenderer - extend Forwardable - - private def_delegator :@site, :in_source_dir, :source_dir - private def_delegator :@site, :in_theme_dir, :theme_dir - def initialize(site) @site = site Liquid::Template.error_mode = @site.config["liquid"]["error_mode"].to_sym @@ -22,13 +17,7 @@ def reset end def file(filename) - filename.match(filename_regex) - filename = - if Regexp.last_match(1) == theme_dir("") - ::File.join(::File.basename(Regexp.last_match(1)), Regexp.last_match(2)) - else - Regexp.last_match(2) - end + filename = normalize_path(filename) LiquidRenderer::File.new(self, filename).tap do @stats[filename] ||= new_profile_hash end @@ -64,9 +53,23 @@ def cache private - def filename_regex - @filename_regex ||= begin - %r!\A(#{Regexp.escape(source_dir)}/|#{Regexp.escape(theme_dir.to_s)}/|/*)(.*)!i + def normalize_path(filename) + @normalize_path ||= {} + @normalize_path[filename] ||= begin + theme_dir = @site.theme&.root + case filename + when %r!\A(#{Regexp.escape(@site.source)}/)(?.*)!io + Regexp.last_match(:rest) + when %r!(/gems/.*)*/gems/(?[^/]+)(?.*)!, + %r!(?[^/]+/lib)(?.*)! + "#{Regexp.last_match(:dirname)}#{Regexp.last_match(:rest)}" + when theme_dir && %r!\A#{Regexp.escape(theme_dir)}/(?.*)!io + PathManager.join(@site.theme.basename, Regexp.last_match(:rest)) + when %r!\A/(.*)! + Regexp.last_match(1) + else + filename + end end end diff --git a/lib/jekyll/theme.rb b/lib/jekyll/theme.rb index 5ef4d044504..3e5172f7ab0 100644 --- a/lib/jekyll/theme.rb +++ b/lib/jekyll/theme.rb @@ -21,6 +21,11 @@ def root "or includes a symbolic link loop" end + # The name of theme directory + def basename + @basename ||= File.basename(root) + end + def includes_path @includes_path ||= path_for "_includes" end diff --git a/test/test_liquid_renderer.rb b/test/test_liquid_renderer.rb index 8739ada54ea..40795801f51 100644 --- a/test/test_liquid_renderer.rb +++ b/test/test_liquid_renderer.rb @@ -26,5 +26,33 @@ class TestLiquidRenderer < JekyllUnitTest assert_match regexp, output end end + + should "normalize paths of rendered items" do + site = fixture_site("theme" => "test-theme") + MockRenderer = Class.new(Jekyll::LiquidRenderer) { public :normalize_path } + renderer = MockRenderer.new(site) + + assert_equal "feed.xml", renderer.normalize_path("/feed.xml") + assert_equal( + "_layouts/post.html", + renderer.normalize_path(site.in_source_dir("_layouts", "post.html")) + ) + assert_equal( + "test-theme/_layouts/page.html", + renderer.normalize_path(site.in_theme_dir("_layouts", "page.html")) + ) + assert_equal( + "my_plugin-0.1.0/lib/my_plugin/layout.html", + renderer.normalize_path( + "/users/jo/blog/vendor/bundle/ruby/2.4.0/gems/my_plugin-0.1.0/lib/my_plugin/layout.html" + ) + ) + assert_equal( + "test_plugin-0.1.0/lib/test_plugin/layout.html", + renderer.normalize_path( + "C:/Ruby2.4/lib/ruby/gems/2.4.0/gems/test_plugin-0.1.0/lib/test_plugin/layout.html" + ) + ) + end end end