diff --git a/Gemfile b/Gemfile index b1a644992..8da7c0735 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,9 @@ source 'https://rubygems.org' - gemspec :name => 'gollum-lib' +gem 'irb' + +if RUBY_PLATFORM == 'java' then + group :development do + gem 'activesupport', '~> 6.0' + end +end diff --git a/HISTORY.md b/HISTORY.md index 54a03832f..b2cbfed96 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,13 +2,10 @@ * Bugfix release: address XSS vulnerability ( @6661620a, @dometto) - # 5.2.3 / 2023-03-13 * Bugfix release: update adapter dependencies for Ruby 3.2 support. - - # 5.2.2 / 2023-01-18 * Bugfix release: set Nokogiri default XHTML conversion options more relaibly. See https://github.com/sparklemotion/nokogiri/issues/2761 diff --git a/LATEST_CHANGES.md b/LATEST_CHANGES.md index a97b5badf..230f14b0c 100644 --- a/LATEST_CHANGES.md +++ b/LATEST_CHANGES.md @@ -1,3 +1,21 @@ +<<<<<<< HEAD # 5.2.4 / 2023-03-22 * Bugfix release: address XSS vulnerability ( @6661620a, @dometto) +======= +# 6.0 + +* Default to local PlantUML server for security. #412. (@manofstick) +* Allow use of default branch name `main` or `master. Resolves https://github.com/gollum/gollum/issues/1813. (@dometto) +<<<<<<< HEAD +>>>>>>> 462ce53 (Implement default branch detection, move away from master as default. (#424)) +======= +* Support use of commit notes in Gollum::Committer. (@dometto, @bartkamphorst) +<<<<<<< HEAD +>>>>>>> 8384b51 (Support for git notes (#435)) +======= + +### Bugfixes + +* Fix the use of boolean arguments in Macros. #441. (@dometto) +>>>>>>> 0db2ff5 (Ensure boolean Macro arguments are parsed as boolean. Resolves #441 (#447)) diff --git a/gemspec.rb b/gemspec.rb index 16492e7eb..ebe3f378a 100644 --- a/gemspec.rb +++ b/gemspec.rb @@ -26,14 +26,13 @@ def specification(version, default_adapter, platform = nil) s.add_dependency 'loofah', '~> 2.3' s.add_dependency 'github-markup', '~> 4.0' s.add_dependency 'gemojione', '~> 4.1' - s.add_dependency 'octicons', '~> 12.0' s.add_dependency 'twitter-text', '1.14.7' s.add_development_dependency 'org-ruby', '~> 0.9.9' s.add_development_dependency 'kramdown', '~> 2.3' s.add_development_dependency 'kramdown-parser-gfm', '~> 1.1.0' s.add_development_dependency 'RedCloth', '~> 4.2.9' - s.add_development_dependency 'mocha', '~> 1.11' + s.add_development_dependency 'mocha', '~> 2.0' s.add_development_dependency 'shoulda', '~> 4.0' s.add_development_dependency 'wikicloth', '~> 0.8.3' s.add_development_dependency 'bibtex-ruby', '~> 6.0' @@ -45,7 +44,7 @@ def specification(version, default_adapter, platform = nil) s.add_development_dependency 'rb-readline', '~> 0.5.1' # updating minitest-reporters requires a new minitest which fails with gollum's tests. s.add_development_dependency 'test-unit', '~> 3.3' - s.add_development_dependency 'minitest-reporters', '~> 1.4' + s.add_development_dependency 'minitest-reporters', '~> 1.5' s.add_development_dependency 'nokogiri-diff', '~> 0.2.0' s.add_development_dependency 'guard', '~> 2.16' s.add_development_dependency 'guard-minitest', '~> 2.4' @@ -93,7 +92,7 @@ def specification(version, default_adapter, platform = nil) lib/gollum-lib/macro/global_toc.rb lib/gollum-lib/macro/navigation.rb lib/gollum-lib/macro/note.rb - lib/gollum-lib/macro/octicon.rb + lib/gollum-lib/macro/icon.rb lib/gollum-lib/macro/series.rb lib/gollum-lib/macro/video.rb lib/gollum-lib/macro/warn.rb diff --git a/gollum-lib.gemspec b/gollum-lib.gemspec index 3411abb06..7348e652c 100644 --- a/gollum-lib.gemspec +++ b/gollum-lib.gemspec @@ -3,8 +3,8 @@ require File.join(File.dirname(__FILE__), 'lib', 'gollum-lib', 'version.rb') # This file needs to conditionally define the default adapter for MRI and Java, because this is the file that is included from the Gemfile. # In addition, the default Java adapter needs to be defined in gollum-lib_java.gemspec beause that file is used to *build* the Java gem. if RUBY_PLATFORM == 'java' then - default_adapter = ['gollum-rjgit_adapter', '~> 1.0'] + default_adapter = ['gollum-rjgit_adapter', '~> 2.0'] else - default_adapter = ['gollum-rugged_adapter', '~> 2.0'] + default_adapter = ['gollum-rugged_adapter', '~> 3.0'] end Gem::Specification.new &specification(Gollum::Lib::VERSION, default_adapter) diff --git a/gollum-lib_java.gemspec b/gollum-lib_java.gemspec index 02e7a28ad..62772a087 100644 --- a/gollum-lib_java.gemspec +++ b/gollum-lib_java.gemspec @@ -1,4 +1,4 @@ require File.join(File.dirname(__FILE__), 'gemspec.rb') require File.join(File.dirname(__FILE__), 'lib', 'gollum-lib', 'version.rb') -default_adapter = ['gollum-rjgit_adapter', '~> 0.6'] +default_adapter = ['gollum-rjgit_adapter', '~> 2.0'] Gem::Specification.new &specification(Gollum::Lib::VERSION, default_adapter, "java") diff --git a/lib/gollum-lib/committer.rb b/lib/gollum-lib/committer.rb index af200ff40..103f1293a 100644 --- a/lib/gollum-lib/committer.rb +++ b/lib/gollum-lib/committer.rb @@ -18,6 +18,7 @@ class Committer # :message - The String commit message. # :name - The String author full name. # :email - The String email address. + # :note - Optional String containing info about the commit. Not used, but can be accessed from inside the :post_commit Hook. # :parent - Optional Gollum::Git::Commit parent to this update. # :tree - Optional String SHA of the tree to create the # index from. @@ -128,6 +129,7 @@ def commit @callbacks.each do |cb| cb.call(self, sha1) end + @wiki.repo.commit(sha1).note=@options[:note] if @options[:note] Hook.execute(:post_commit, self, sha1) sha1 end diff --git a/lib/gollum-lib/file.rb b/lib/gollum-lib/file.rb index f17ac8ad1..62bdfab54 100644 --- a/lib/gollum-lib/file.rb +++ b/lib/gollum-lib/file.rb @@ -8,18 +8,21 @@ class File class << self - # For use with self.find: returns true if the given query corresponds to the in-repo path of the BlobEntry. - # - # query - The String path to match. - # entry - The BlobEntry to check against. - # global_match - (Not implemented for File, see Page.path_match) - # hyphened_tags - If true, replace spaces in match_path with hyphens. - # case_insensitive - If true, compare query and match_path case-insensitively - def path_match(query, entry, global_match = false, hyphened_tags = false, case_insensitive = false) - path_compare(query, ::File.join('/', entry.path), hyphened_tags, case_insensitive) - end + # Get a canonical path to a file. + # Ensures that the result is always under page_file_dir (prevents path traversal), if set. + # Removes leading slashes. + # + # path - One or more String path elements to join together. `nil` values are ignored. + # page_file_dir - kwarg String, default: nil + def canonical_path(*path, page_file_dir: nil) + prefix = Pathname.new('/') + page_file_dir.to_s + rest = Pathname.new('/').join(*path.compact).cleanpath.to_s[1..-1] + result = (prefix + rest).cleanpath.to_s[1..-1] + result.sub!(/^\/+/, '') if Gem.win_platform? # On Windows, Pathname#cleanpath will leave double slashes at the start of a path, so replace all (not just the first) leading slashes + result + end - # For use with self.path_match: returns true if 'query' and 'match_path' match, strictly or taking account of the following parameters: + # For use with self.find: returns true if 'query' and 'match_path' match, strictly or taking account of the following parameters: # hyphened_tags - If true, replace spaces in match_path with hyphens. # case_insensitive - If true, compare query and match_path case-insensitively def path_compare(query, match_path, hyphened_tags, case_insensitive) @@ -41,24 +44,31 @@ def path_compare(query, match_path, hyphened_tags, case_insensitive) # version - The String version ID to find. # try_on_disk - If true, try to return just a reference to a file # that exists on the disk. - # global_match - If true, find a File matching path's filename, but not it's directory (so anywhere in the repo) + # global_match - If true, find a File matching path's filename, but not its directory (so anywhere in the repo) # # Returns a Gollum::File or nil if the file could not be found. Note # that if you specify try_on_disk=true, you may or may not get a file # for which on_disk? is actually true. def self.find(wiki, path, version, try_on_disk = false, global_match = false) - map = wiki.tree_map_for(version.to_s) - - query_path = Pathname.new(::File.join(['/', wiki.page_file_dir, path].compact)).cleanpath.to_s - query_path.sub!(/^\/\//, '/') if Gem.win_platform? # On Windows, Pathname#cleanpath will leave double slashes at the start of a path intact, so sub them out. + query_path = self.canonical_path(path, page_file_dir: wiki.page_file_dir) + dir, filename = Pathname.new(query_path).split + dir = dir.to_s - begin - entry = map.detect do |entry| - path_match(query_path, entry, global_match, wiki.hyphened_tag_lookup, wiki.case_insensitive_tag_lookup) + if global_match && self.respond_to?(:global_find) # Only implemented for Gollum::Page + return self.global_find(wiki, version, query_path, try_on_disk) + else + begin + root = wiki.commit_for(version) + return nil unless root + tree = dir == '.' ? root.tree : root.tree / dir + return nil unless tree + entry = tree.find_blob do |blob_name| + path_compare(filename.to_s, blob_name, wiki.hyphened_tag_lookup, wiki.case_insensitive_tag_lookup) + end + entry ? self.new(wiki, entry, dir, version, try_on_disk) : nil + rescue Gollum::Git::NoSuchShaFound + nil end - entry ? self.new(wiki, entry.blob(wiki.repo), entry.dir, version, try_on_disk) : nil - rescue Gollum::Git::NoSuchShaFound - nil end end @@ -74,7 +84,7 @@ def self.find(wiki, path, version, try_on_disk = false, global_match = false) def initialize(wiki, blob, path, version, try_on_disk = false) @wiki = wiki @blob = blob - @path = "#{path}/#{blob.name}"[1..-1] + @path = self.class.canonical_path(path, blob.name) @version = version.is_a?(Gollum::Git::Commit) ? version : @wiki.commit_for(version) get_disk_reference if try_on_disk end diff --git a/lib/gollum-lib/filter/macro.rb b/lib/gollum-lib/filter/macro.rb index 2023b3f9d..03e0ba88e 100644 --- a/lib/gollum-lib/filter/macro.rb +++ b/lib/gollum-lib/filter/macro.rb @@ -1,5 +1,5 @@ # ~*~ encoding: utf-8 ~*~ -require 'octicons' + # Replace specified tokens with dynamically generated content. class Gollum::Filter::Macro < Gollum::Filter @@ -22,13 +22,18 @@ def extract(data) argstr.scan(/,?\s*(#{arg})\s*/) do |arguments| # Stabstabstab argument = arguments.first - - if argument =~ /^([a-z0-9_]+)="(.*?)"/ - opts[Regexp.last_match[1]] = Regexp.last_match[2] - elsif argument =~ /^"(.*)"$/ - args << Regexp.last_match[1].gsub("\\\"", "\"") - else - args << argument + + case argument + in /^([a-z0-9_]+)="(.*?)"/ + opts[Regexp.last_match[1]] = Regexp.last_match[2] + in /^"(.*)"$/ + args << Regexp.last_match[1].gsub("\\\"", "\"") + in /\s*false\s*/ + args << false + in /\s*true\s*/ + args << true + else + args << argument end end @@ -48,13 +53,11 @@ def process(data) begin Gollum::Macro.instance(macro, @markup.wiki, @markup.page).render(*args) rescue StandardError => e - icon = Octicons::Octicon.new('zap', {width: 24, height: 24}) - icon.options[:class] << ' mr-2' - "
#{icon.to_svg}Macro Error for #{macro}: #{e.message}
" + %Q(
Macro Error for #{macro}: #{e.message}
) end end end - sanitize(data) + data end end diff --git a/lib/gollum-lib/filter/plantuml.rb b/lib/gollum-lib/filter/plantuml.rb index 905834167..e413f21b3 100644 --- a/lib/gollum-lib/filter/plantuml.rb +++ b/lib/gollum-lib/filter/plantuml.rb @@ -37,7 +37,7 @@ # class Gollum::Filter::PlantUML < Gollum::Filter - DEFAULT_URL = "http://www.plantuml.com/plantuml/png" + DEFAULT_URL = "http://localhost:8080/plantuml/png" # Configuration class used to change the behaviour of the PlatnUML filter. # diff --git a/lib/gollum-lib/filter/render.rb b/lib/gollum-lib/filter/render.rb index b394826fe..560a9bcc2 100644 --- a/lib/gollum-lib/filter/render.rb +++ b/lib/gollum-lib/filter/render.rb @@ -6,7 +6,11 @@ def extract(data) working_dir = Pathname.new(@markup.wiki.path).join(@markup.dir) working_dir = working_dir.exist? ? working_dir.to_s : '.' Dir.chdir(working_dir) do - data = GitHub::Markup.render_s(@markup.format, data) + if block = @markup.custom_renderer + data = block.call(data) + else + data = GitHub::Markup.render_s(@markup.format, data) + end end if data.nil? raise "There was an error converting #{@markup.name} to HTML." diff --git a/lib/gollum-lib/filter/tags.rb b/lib/gollum-lib/filter/tags.rb index 2fd9d00ec..0808701ee 100644 --- a/lib/gollum-lib/filter/tags.rb +++ b/lib/gollum-lib/filter/tags.rb @@ -231,7 +231,13 @@ def process_page_link_tag(link_part, pretty_name = nil) name = page ? path_to_link_text(link) : link end - link = page ? page.escaped_url_path : ERB::Util.url_encode(link).force_encoding('utf-8') + if page + link = page.escaped_url_path + else + link = Pathname.new(link).relative? ? "#{@markup.dir.to_s}/#{link}" : link + link = ERB::Util.url_encode(link).force_encoding('utf-8') + end + generate_link(link, name, extra, presence) end diff --git a/lib/gollum-lib/git_access.rb b/lib/gollum-lib/git_access.rb index 1967359c4..2b010c07a 100644 --- a/lib/gollum-lib/git_access.rb +++ b/lib/gollum-lib/git_access.rb @@ -161,15 +161,11 @@ def tree!(sha) items = [] tree.each do |entry| if entry[:type] == 'blob' - items << BlobEntry.new(entry[:sha], entry[:path], entry[:size], entry[:mode].to_i(8)) + next if @page_file_dir && !entry[:path].start_with?("#{@page_file_dir}/") + items << BlobEntry.new(entry[:sha], entry[:path], entry[:size], entry[:mode]) end end - if (dir = @page_file_dir) - regex = /^#{dir}\// - items.select { |i| i.path =~ regex } - else - items - end + items end # Reads the content from the Git db at the given SHA. diff --git a/lib/gollum-lib/helpers.rb b/lib/gollum-lib/helpers.rb index 081805501..7870c6468 100644 --- a/lib/gollum-lib/helpers.rb +++ b/lib/gollum-lib/helpers.rb @@ -3,12 +3,12 @@ module Gollum module Helpers - # If url starts with a leading slash, trim down its number of leading slashes to 1. Else, return url unchanged. + # Replace url-encoded slashes ('%2F') with slashes + # Clean up double slashes def trim_leading_slashes(url) return nil if url.nil? url.gsub!('%2F', '/') - return '/' + url.gsub(/^\/+/, '') if url[0, 1] == '/' - url + Pathname.new(url).cleanpath.to_s end # Take a link path and turn it into a string for display as link text. diff --git a/lib/gollum-lib/macro.rb b/lib/gollum-lib/macro.rb index 870bf4750..077c645d0 100644 --- a/lib/gollum-lib/macro.rb +++ b/lib/gollum-lib/macro.rb @@ -38,7 +38,7 @@ def initialize(macro_name) end def render(*_args) - "!!!Unknown macro: #{@macro_name}!!!" + html_error("Unknown macro: #{@macro_name}") end end end diff --git a/lib/gollum-lib/macro/flash.rb b/lib/gollum-lib/macro/flash.rb new file mode 100644 index 000000000..9c7a91890 --- /dev/null +++ b/lib/gollum-lib/macro/flash.rb @@ -0,0 +1,11 @@ +module Gollum + class Macro + class Flash < Gollum::Macro + def render(message, icon='', type='') + flash_type = ['warn', 'error', 'success'].include?(type) ? "flash-#{type}" : '' + flash_icon = icon.empty? ? '' : %Q(data-gollum-icon="#{icon}") + %Q(
#{message}
) + end + end + end +end \ No newline at end of file diff --git a/lib/gollum-lib/macro/icon.rb b/lib/gollum-lib/macro/icon.rb new file mode 100644 index 000000000..7b9bdd8bf --- /dev/null +++ b/lib/gollum-lib/macro/icon.rb @@ -0,0 +1,9 @@ +module Gollum + class Macro + class Icon < Gollum::Macro + def render(icon) + %Q(
) + end + end + end +end \ No newline at end of file diff --git a/lib/gollum-lib/macro/note.rb b/lib/gollum-lib/macro/note.rb index 4c0a7c7bf..67133b430 100644 --- a/lib/gollum-lib/macro/note.rb +++ b/lib/gollum-lib/macro/note.rb @@ -1,18 +1,8 @@ module Gollum class Macro class Note < Gollum::Macro - def render(notice, octicon = 'info') - icon = "" - unless octicon.empty? - begin - icon = Octicons::Octicon.new(octicon, {width: 24, height: 24}) - rescue RuntimeError - icon = Octicons::Octicon.new('info', {width: 24, height: 24}) - end - icon.options[:class] << ' mr-2' - icon = icon.to_svg - end - "
#{icon}#{notice}
" + def render(notice) + %Q(
#{notice}
) end end end diff --git a/lib/gollum-lib/macro/octicon.rb b/lib/gollum-lib/macro/octicon.rb deleted file mode 100644 index de8ab8ff0..000000000 --- a/lib/gollum-lib/macro/octicon.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Gollum - class Macro - class Octicon < Gollum::Macro - def render(symbol, height = nil, width = nil) - parameters = {} - parameters[:height] = height if height - parameters[:width] = width if width - "
#{Octicons::Octicon.new(symbol, parameters).to_svg}
" - end - end - end -end \ No newline at end of file diff --git a/lib/gollum-lib/macro/warn.rb b/lib/gollum-lib/macro/warn.rb index 892b8a36d..1e7cc502b 100644 --- a/lib/gollum-lib/macro/warn.rb +++ b/lib/gollum-lib/macro/warn.rb @@ -2,9 +2,7 @@ module Gollum class Macro class Warn < Gollum::Macro def render(warning) - icon = Octicons::Octicon.new('alert', {width: 24, height: 24}) - icon.options[:class] << ' mr-2' - "
#{icon.to_svg}#{warning}
" + %Q(
#{warning}
) end end end diff --git a/lib/gollum-lib/markup.rb b/lib/gollum-lib/markup.rb index c39f9ec69..d4189eb0d 100644 --- a/lib/gollum-lib/markup.rb +++ b/lib/gollum-lib/markup.rb @@ -61,7 +61,9 @@ def register(ext, name, options = {}, &block) :extensions => new_extension, :reverse_links => options.fetch(:reverse_links, false), :skip_filters => options.fetch(:skip_filters, nil), - :enabled => options.fetch(:enabled, true) } + :enabled => options.fetch(:enabled, true), + :render => options.fetch(:render, nil) + } @extensions.concat(new_extension) end end @@ -102,6 +104,10 @@ def reverse_links? self.class.formats[@format][:reverse_links] end + def custom_renderer + self.class.formats[@format].fetch(:render, nil) + end + # Whether or not a particular filter should be skipped for this format. def skip_filter?(filter) if self.class.formats[@format][:skip_filters].respond_to?(:include?) @@ -119,7 +125,7 @@ def skip_filter?(filter) # filter_chain - the chain to process # # Returns the formatted data - def process_chain(data, filter_chain) + def process_chain(data, filter_chain, &block) # First we extract the data through the chain... filter_chain.each do |filter| data = filter.extract(data) diff --git a/lib/gollum-lib/page.rb b/lib/gollum-lib/page.rb index 85163fc2f..0464b2a7a 100644 --- a/lib/gollum-lib/page.rb +++ b/lib/gollum-lib/page.rb @@ -6,22 +6,39 @@ class Page < Gollum::File SUBPAGENAMES = [:header, :footer, :sidebar] class << self - # For use with self.find: returns true if the given query corresponds to the in-repo path of the BlobEntry. + # For use with self.global_find: returns true if the given query corresponds to the in-repo path of the BlobEntry. # # query - The String path to match. # entry - The BlobEntry to check against. - # global_match - If true, find a File matching path's filename, but not its directory (so anywhere in the repo) - def path_match(query, entry, global_match = false, hyphened_tags = false, case_insensitive = false) + def global_path_match(query, entry, hyphened_tags = false, case_insensitive = false) return false if "#{entry.name}".empty? return false unless valid_extension?(entry.name) - entry_name = valid_extension?(query) ? entry.name : strip_filename(entry.name) - match_path = ::File.join([ - '/', - global_match ? nil : entry.dir, - entry_name - ].compact) + match_path = Pathname.new('/').join(*[ + entry.dir, + entry.name + ].compact + ).to_s path_compare(query, match_path, hyphened_tags, case_insensitive) end + + def global_find(wiki, version, query, try_on_disk) + map = wiki.tree_map_for(version.to_s) + begin + entry = map.detect do |entry| + global_path_match(query, entry, wiki.hyphened_tag_lookup, wiki.case_insensitive_tag_lookup) + end + entry ? self.new(wiki, entry.blob(wiki.repo), entry.dir, version, try_on_disk) : nil + rescue Gollum::Git::NoSuchShaFound + nil + end + end + + def path_compare(query, match_path, hyphened_tags, case_insensitive) + return false unless valid_extension?(match_path) + cmp = valid_extension?(query) ? match_path : strip_filename(match_path) + super(query, cmp, hyphened_tags, case_insensitive) + end + end # Checks if a filename has a valid, registered extension diff --git a/lib/gollum-lib/wiki.rb b/lib/gollum-lib/wiki.rb index a0cc87109..920399fb4 100644 --- a/lib/gollum-lib/wiki.rb +++ b/lib/gollum-lib/wiki.rb @@ -7,7 +7,7 @@ class Wiki class << self # Sets the default ref for the wiki. - attr_writer :default_ref + attr_writer :default_refs # Sets the default name for commits. attr_writer :default_committer_name @@ -19,8 +19,12 @@ class << self # These defaults can be overridden by options passed directly to initialize() attr_writer :default_options - def default_ref - @default_ref || 'master' + def find_default_ref(repo) + repo.find_branch(self.default_refs) || Gollum::Git.global_default_branch || self.default_refs.first + end + + def default_refs + @default_refs || ['master', 'main'] end def default_committer_name @@ -132,7 +136,7 @@ def initialize(path, options = {}) @access = options.fetch :access, GitAccess.new(path, @page_file_dir, @repo_is_bare) @base_path = options.fetch :base_path, "/" @repo = @access.repo - @ref = options.fetch :ref, self.class.default_ref + @ref = options.fetch :ref, self.class.find_default_ref(@repo) @universal_toc = options.fetch :universal_toc, false @mathjax = options.fetch :mathjax, false @global_tag_lookup = options.fetch :global_tag_lookup, false diff --git a/test/helper.rb b/test/helper.rb index cb11ecb3a..9c50c72b1 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -6,8 +6,8 @@ # external require 'rubygems' require 'shoulda' -require 'mocha/test_unit' require 'minitest/reporters' +require 'mocha/test_unit' require 'twitter_cldr' require 'tempfile' @@ -24,7 +24,7 @@ require 'i18n' I18n.enforce_available_locales = false -MiniTest::Reporters.use! +Minitest::Reporters.use! dir = File.dirname(File.expand_path(__FILE__)) $LOAD_PATH.unshift(File.join(dir, '..', 'lib')) diff --git a/test/test_committer.rb b/test/test_committer.rb index a8118796e..439818e0f 100644 --- a/test/test_committer.rb +++ b/test/test_committer.rb @@ -135,3 +135,20 @@ @wiki.update_page(page, page.name, format, "# Elrond", commit_details()) end end + +context "Committer with a writable wiki" do + setup do + @path = cloned_testpath("examples/lotr.git") + @wiki = Gollum::Wiki.new(@path) + end + + test "supports notes" do + committer = Gollum::Committer.new(@wiki, note: 'My notes') + committer.commit + assert_equal @wiki.repo.head.commit.note, 'My notes' + end + + teardown do + FileUtils.rm_rf(@path) + end +end \ No newline at end of file diff --git a/test/test_file.rb b/test/test_file.rb index af5876de9..7c744f4ac 100644 --- a/test/test_file.rb +++ b/test/test_file.rb @@ -7,6 +7,17 @@ @wiki = Gollum::Wiki.new(testpath("examples/lotr.git")) end + test 'canonical_path method does not allow path traversal exploit' do + page_file_dir = nil + dir = 'pages' + file = '../../' + assert_equal Gollum::File.canonical_path(dir, file, page_file_dir: page_file_dir), '' + page_file_dir = 'pages' + assert_equal Gollum::File.canonical_path(dir, file, page_file_dir: page_file_dir), 'pages' + # also removes leading slashes + assert_equal Gollum::File.canonical_path('/foo/bar', page_file_dir: page_file_dir), 'pages/foo/bar' + end + test "existing file" do commit = @wiki.repo.commits.first file = @wiki.file("Mordor/todo.txt") diff --git a/test/test_macros.rb b/test/test_macros.rb index c13754241..d3fb0f6be 100644 --- a/test/test_macros.rb +++ b/test/test_macros.rb @@ -50,6 +50,13 @@ def render(opts) assert_match /
Navigate this directory<\/div>