diff --git a/benchmark/jekyll-sanitize-path b/benchmark/jekyll-sanitize-path new file mode 100644 index 00000000..231de275 --- /dev/null +++ b/benchmark/jekyll-sanitize-path @@ -0,0 +1,46 @@ +#!/usr/bin/env ruby + +require_relative '../lib/jekyll' +require 'benchmark/ips' + +base_directory = Dir.pwd + +Benchmark.ips do |x| + # + # Does not include the base_directory + # + x.report('with no questionable path') do + Jekyll.sanitized_path(base_directory, '') + end + x.report('with a single-part questionable path') do + Jekyll.sanitized_path(base_directory, 'thingy') + end + x.report('with a multi-part questionable path') do + Jekyll.sanitized_path(base_directory, 'thingy/in/my/soup') + end + x.report('with a single-part traversal path') do + Jekyll.sanitized_path(base_directory, '../thingy') + end + x.report('with a multi-part traversal path') do + Jekyll.sanitized_path(base_directory, '../thingy/in/my/../../soup') + end + + # + # Including the base_directory + # + x.report('with the exact same paths') do + Jekyll.sanitized_path(base_directory, base_directory) + end + x.report('with a single-part absolute path including the base_directory') do + Jekyll.sanitized_path(base_directory, File.join(base_directory, 'thingy')) + end + x.report('with a multi-part absolute path including the base_directory') do + Jekyll.sanitized_path(base_directory, File.join(base_directory, 'thingy/in/my/soup')) + end + x.report('with a single-part traversal path including the base_directory') do + Jekyll.sanitized_path(base_directory, File.join(base_directory, 'thingy/..')) + end + x.report('with a multi-part traversal path including the base_directory') do + Jekyll.sanitized_path(base_directory, File.join('thingy/in/my/../../soup')) + end +end diff --git a/lib/jekyll.rb b/lib/jekyll.rb index 137d5894..ce94b64b 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -141,9 +141,12 @@ module Jekyll # # Returns the sanitized path. def sanitized_path(base_directory, questionable_path) + return base_directory if base_directory.eql?(questionable_path) + clean_path = File.expand_path(questionable_path, "/") - clean_path.gsub!(/\A\w\:\//, '/') - unless clean_path.start_with?(base_directory) + clean_path = clean_path.sub(/^\A\w\:\//, '/') + + unless clean_path.start_with?(base_directory.sub(/^\A\w\:\//, '/')) File.join(base_directory, clean_path) else clean_path