diff --git a/lib/gollum/app.rb b/lib/gollum/app.rb index 1a043a56..a8b9abab 100644 --- a/lib/gollum/app.rb +++ b/lib/gollum/app.rb @@ -101,7 +101,7 @@ module Precious # name, path, version def wiki_page(name, path = nil, version = nil, exact = true) wiki = wiki_new - + path = name if path.nil? name = extract_name(name) || wiki.index_page path = extract_path(path) @@ -125,7 +125,7 @@ module Precious wikip = wiki_page(params[:splat].first) @name = wikip.name @path = wikip.path - + wiki = wikip.wiki if page = wikip.page if wiki.live_preview && page.format.to_s.include?('markdown') && supported_useragent?(request.user_agent) @@ -222,6 +222,7 @@ module Precious # not /docs/Home because write_page will append /docs @path = @path.sub(page_dir, '/') if @path.start_with? page_dir end + @path = clean_path(@path) page = wikip.page if page @@ -393,14 +394,14 @@ module Precious @page = page @name = name @content = page.formatted_data - + # Extensions and layout data @editable = true @toc_content = wiki.universal_toc ? @page.toc_data : nil @mathjax = wiki.mathjax @h1_title = wiki.h1_title @bar_side = wiki.bar_side - + mustache :page elsif file = wiki.file(fullpath) content_type file.mime_type diff --git a/lib/gollum/helpers.rb b/lib/gollum/helpers.rb index e9145a0a..1354f862 100644 --- a/lib/gollum/helpers.rb +++ b/lib/gollum/helpers.rb @@ -15,8 +15,8 @@ module Precious if file_path[-1, 1] == "/" return nil end - - # File.basename is too eager to please and will return the last + + # File.basename is too eager to please and will return the last # component of the path even if it ends with a directory separator. ::File.basename(file_path) end @@ -25,6 +25,13 @@ module Precious [nil,''].include?(param) ? nil : CGI.unescape(param) end + # Ensure path begins with a single leading slash + def clean_path(path) + if path + (path[0] != '/' ? path.insert(0, '/') : path).gsub(/\/{2,}/,'/') + end + end + # Remove all slashes from the start of string. # Remove all double slashes def clean_url url diff --git a/test/test_app.rb b/test/test_app.rb index 6ee2bf03..c7fb3aad 100644 --- a/test/test_app.rb +++ b/test/test_app.rb @@ -279,7 +279,7 @@ context "Frontend" do :format => 'markdown', :message => 'foo' assert_equal "http://example.org/foo/home", last_response.headers['Location'] - + follow_redirect! assert last_response.ok? end @@ -300,6 +300,25 @@ context "Frontend" do assert last_response.ok? end + test "create sets the correct path for a relative path subdirectory" do + dir = "foodir" + name = "#{dir}/bar" + get "/create/#{name}" + assert_match(/\/#{dir}/, last_response.body) + assert_no_match(/[^\/]#{dir}/, last_response.body) + end + + test "create sets the correct path for a relative path subdirectory with the page file directory set" do + Precious::App.set(:wiki_options, {:page_file_dir => "foo"}) + dir = "bardir" + name = "#{dir}/baz" + get "/create/foo/#{name}" + assert_match(/\/#{dir}/, last_response.body) + assert_no_match(/[^\/]#{dir}/, last_response.body) + # reset page_file_dir + Precious::App.set(:wiki_options, {:page_file_dir => nil}) + end + test "edit returns nil for non-existant page" do # post '/edit' fails. post '/edit/' works. page = 'not-real-page' @@ -442,20 +461,20 @@ context "Frontend" do Precious::App.set(:wiki_options, { :base_path => nil }) end =end - + test "author details in session are used" do page1 = @wiki.page('A') - + gollum_author = { :name => 'ghi', :email => 'jkl' } session = { 'gollum.author' => gollum_author } - + post "/edit/A", { :content => 'abc', :page => 'A', :format => page1.format, :message => 'def' }, { 'rack.session' => session } follow_redirect! assert last_response.ok? - + @wiki.clear_cache page2 = @wiki.page(page1.name) - + author = page2.version.author assert_equal 'ghi', author.name assert_equal 'jkl', author.email diff --git a/test/test_app_helpers.rb b/test/test_app_helpers.rb index e2946e8e..549afff2 100644 --- a/test/test_app_helpers.rb +++ b/test/test_app_helpers.rb @@ -9,5 +9,17 @@ context "Precious::Helpers" do assert_equal 'Mordor', extract_path('Mordor/Sauron') assert_equal 'Mordor/Sauron', extract_path('Mordor/Sauron/Evil') end + + test "clean path without leading slash" do + assert_equal '/Mordor', clean_path('Mordor') + end + + test "clean path with leading slash" do + assert_equal '/Mordor', clean_path('/Mordor') + end + + test "clean path with double leading slash" do + assert_equal '/Mordor', clean_path('//Mordor') + end end