Merge pull request #698 from ddeyoung/improve-page-create
Leaving off the leading slash in a page name with a subdirectory will corrupt the repository
This commit is contained in:
+5
-4
@@ -101,7 +101,7 @@ module Precious
|
|||||||
# name, path, version
|
# name, path, version
|
||||||
def wiki_page(name, path = nil, version = nil, exact = true)
|
def wiki_page(name, path = nil, version = nil, exact = true)
|
||||||
wiki = wiki_new
|
wiki = wiki_new
|
||||||
|
|
||||||
path = name if path.nil?
|
path = name if path.nil?
|
||||||
name = extract_name(name) || wiki.index_page
|
name = extract_name(name) || wiki.index_page
|
||||||
path = extract_path(path)
|
path = extract_path(path)
|
||||||
@@ -125,7 +125,7 @@ module Precious
|
|||||||
wikip = wiki_page(params[:splat].first)
|
wikip = wiki_page(params[:splat].first)
|
||||||
@name = wikip.name
|
@name = wikip.name
|
||||||
@path = wikip.path
|
@path = wikip.path
|
||||||
|
|
||||||
wiki = wikip.wiki
|
wiki = wikip.wiki
|
||||||
if page = wikip.page
|
if page = wikip.page
|
||||||
if wiki.live_preview && page.format.to_s.include?('markdown') && supported_useragent?(request.user_agent)
|
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
|
# not /docs/Home because write_page will append /docs
|
||||||
@path = @path.sub(page_dir, '/') if @path.start_with? page_dir
|
@path = @path.sub(page_dir, '/') if @path.start_with? page_dir
|
||||||
end
|
end
|
||||||
|
@path = clean_path(@path)
|
||||||
|
|
||||||
page = wikip.page
|
page = wikip.page
|
||||||
if page
|
if page
|
||||||
@@ -393,14 +394,14 @@ module Precious
|
|||||||
@page = page
|
@page = page
|
||||||
@name = name
|
@name = name
|
||||||
@content = page.formatted_data
|
@content = page.formatted_data
|
||||||
|
|
||||||
# Extensions and layout data
|
# Extensions and layout data
|
||||||
@editable = true
|
@editable = true
|
||||||
@toc_content = wiki.universal_toc ? @page.toc_data : nil
|
@toc_content = wiki.universal_toc ? @page.toc_data : nil
|
||||||
@mathjax = wiki.mathjax
|
@mathjax = wiki.mathjax
|
||||||
@h1_title = wiki.h1_title
|
@h1_title = wiki.h1_title
|
||||||
@bar_side = wiki.bar_side
|
@bar_side = wiki.bar_side
|
||||||
|
|
||||||
mustache :page
|
mustache :page
|
||||||
elsif file = wiki.file(fullpath)
|
elsif file = wiki.file(fullpath)
|
||||||
content_type file.mime_type
|
content_type file.mime_type
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ module Precious
|
|||||||
if file_path[-1, 1] == "/"
|
if file_path[-1, 1] == "/"
|
||||||
return nil
|
return nil
|
||||||
end
|
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.
|
# component of the path even if it ends with a directory separator.
|
||||||
::File.basename(file_path)
|
::File.basename(file_path)
|
||||||
end
|
end
|
||||||
@@ -25,6 +25,13 @@ module Precious
|
|||||||
[nil,''].include?(param) ? nil : CGI.unescape(param)
|
[nil,''].include?(param) ? nil : CGI.unescape(param)
|
||||||
end
|
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 slashes from the start of string.
|
||||||
# Remove all double slashes
|
# Remove all double slashes
|
||||||
def clean_url url
|
def clean_url url
|
||||||
|
|||||||
+25
-6
@@ -279,7 +279,7 @@ context "Frontend" do
|
|||||||
:format => 'markdown', :message => 'foo'
|
:format => 'markdown', :message => 'foo'
|
||||||
|
|
||||||
assert_equal "http://example.org/foo/home", last_response.headers['Location']
|
assert_equal "http://example.org/foo/home", last_response.headers['Location']
|
||||||
|
|
||||||
follow_redirect!
|
follow_redirect!
|
||||||
assert last_response.ok?
|
assert last_response.ok?
|
||||||
end
|
end
|
||||||
@@ -300,6 +300,25 @@ context "Frontend" do
|
|||||||
assert last_response.ok?
|
assert last_response.ok?
|
||||||
end
|
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
|
test "edit returns nil for non-existant page" do
|
||||||
# post '/edit' fails. post '/edit/' works.
|
# post '/edit' fails. post '/edit/' works.
|
||||||
page = 'not-real-page'
|
page = 'not-real-page'
|
||||||
@@ -442,20 +461,20 @@ context "Frontend" do
|
|||||||
Precious::App.set(:wiki_options, { :base_path => nil })
|
Precious::App.set(:wiki_options, { :base_path => nil })
|
||||||
end
|
end
|
||||||
=end
|
=end
|
||||||
|
|
||||||
test "author details in session are used" do
|
test "author details in session are used" do
|
||||||
page1 = @wiki.page('A')
|
page1 = @wiki.page('A')
|
||||||
|
|
||||||
gollum_author = { :name => 'ghi', :email => 'jkl' }
|
gollum_author = { :name => 'ghi', :email => 'jkl' }
|
||||||
session = { 'gollum.author' => gollum_author }
|
session = { 'gollum.author' => gollum_author }
|
||||||
|
|
||||||
post "/edit/A", { :content => 'abc', :page => 'A', :format => page1.format, :message => 'def' }, { 'rack.session' => session }
|
post "/edit/A", { :content => 'abc', :page => 'A', :format => page1.format, :message => 'def' }, { 'rack.session' => session }
|
||||||
follow_redirect!
|
follow_redirect!
|
||||||
assert last_response.ok?
|
assert last_response.ok?
|
||||||
|
|
||||||
@wiki.clear_cache
|
@wiki.clear_cache
|
||||||
page2 = @wiki.page(page1.name)
|
page2 = @wiki.page(page1.name)
|
||||||
|
|
||||||
author = page2.version.author
|
author = page2.version.author
|
||||||
assert_equal 'ghi', author.name
|
assert_equal 'ghi', author.name
|
||||||
assert_equal 'jkl', author.email
|
assert_equal 'jkl', author.email
|
||||||
|
|||||||
@@ -9,5 +9,17 @@ context "Precious::Helpers" do
|
|||||||
assert_equal 'Mordor', extract_path('Mordor/Sauron')
|
assert_equal 'Mordor', extract_path('Mordor/Sauron')
|
||||||
assert_equal 'Mordor/Sauron', extract_path('Mordor/Sauron/Evil')
|
assert_equal 'Mordor/Sauron', extract_path('Mordor/Sauron/Evil')
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user