test/paths_test.rb in asciidoctor-1.5.6.2 vs test/paths_test.rb in asciidoctor-1.5.7

- old
+ new

@@ -87,10 +87,11 @@ assert_equal 'assets/images', @resolver.web_path('', 'assets/images') assert_equal 'assets/images', @resolver.web_path(nil, 'assets/images') end test 'posixifies windows paths' do + @resolver.file_separator = '\\' assert_equal '/images', @resolver.web_path('\\images') assert_equal '../images', @resolver.web_path('..\\images') assert_equal '/images', @resolver.web_path('\\..\\images') assert_equal 'assets/images', @resolver.web_path('assets\\images') assert_equal '../assets/images', @resolver.web_path('assets\\images', '..\\images\\..') @@ -101,33 +102,51 @@ end end context 'System Paths' do JAIL = '/home/doctor/docs' + default_logger = Asciidoctor::LoggerManager.logger def setup @resolver = Asciidoctor::PathResolver.new + @logger = (Asciidoctor::LoggerManager.logger = Asciidoctor::MemoryLogger.new) end - test 'prevents access to paths outside of jail' do - result, warnings = redirect_streams do |_, err| - [(@resolver.system_path '../../../../../css', %(#{JAIL}/assets/stylesheets), JAIL), err.string] + teardown do + Asciidoctor::LoggerManager.logger = default_logger + end + + test 'raises security error if jail is not an absolute path' do + begin + @resolver.system_path('images/tiger.png', '/etc', 'foo') + flunk 'Expecting SecurityError to be raised' + rescue SecurityError end + end + + #test 'raises security error if jail is not a canoncial path' do + # begin + # @resolver.system_path('images/tiger.png', '/etc', %(#{JAIL}/../foo)) + # flunk 'Expecting SecurityError to be raised' + # rescue SecurityError + # end + #end + + test 'prevents access to paths outside of jail' do + result = @resolver.system_path '../../../../../css', %(#{JAIL}/assets/stylesheets), JAIL assert_equal %(#{JAIL}/css), result - assert_includes warnings, 'path has illegal reference to ancestor of jail' + assert_message @logger, :WARN, 'path has illegal reference to ancestor of jail; recovering automatically' - result, warnings = redirect_streams do |_, err| - [(@resolver.system_path '/../../../../../css', %(#{JAIL}/assets/stylesheets), JAIL), err.string] - end + @logger.clear + result = @resolver.system_path '/../../../../../css', %(#{JAIL}/assets/stylesheets), JAIL assert_equal %(#{JAIL}/css), result - assert_includes warnings, 'path has illegal reference to ancestor of jail' + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' - result, warnings = redirect_streams do |_, err| - [(@resolver.system_path '../../../css', '../../..', JAIL), err.string] - end + @logger.clear + result = @resolver.system_path '../../../css', '../../..', JAIL assert_equal %(#{JAIL}/css), result - assert_includes warnings, 'path has illegal reference to ancestor of jail' + assert_message @logger, :WARN, 'path has illegal reference to ancestor of jail; recovering automatically' end test 'throws exception for illegal path access if recover is false' do begin @resolver.system_path('../../../../../css', "#{JAIL}/assets/stylesheets", JAIL, :recover => false) @@ -139,48 +158,114 @@ test 'resolves start path if target is empty' do assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('', "#{JAIL}/assets/stylesheets", JAIL) assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path(nil, "#{JAIL}/assets/stylesheets", JAIL) end + test 'expands parent references in start path if target is empty' do + assert_equal "#{JAIL}/stylesheets", @resolver.system_path('', "#{JAIL}/assets/../stylesheets", JAIL) + end + + test 'expands parent references in start path if target is not empty' do + assert_equal "#{JAIL}/stylesheets/site.css", @resolver.system_path('site.css', "#{JAIL}/assets/../stylesheets", JAIL) + end + test 'resolves start path if target is dot' do assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('.', "#{JAIL}/assets/stylesheets", JAIL) assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('./', "#{JAIL}/assets/stylesheets", JAIL) end - test 'treats absolute target as relative when jail is specified' do - assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('/', "#{JAIL}/assets/stylesheets", JAIL) - assert_equal "#{JAIL}/assets/stylesheets/foo", @resolver.system_path('/foo', "#{JAIL}/assets/stylesheets", JAIL) - assert_equal "#{JAIL}/assets/foo", @resolver.system_path('/../foo', "#{JAIL}/assets/stylesheets", JAIL) + test 'treats absolute target outside of jail as relative when jail is specified' do + result = @resolver.system_path '/', "#{JAIL}/assets/stylesheets", JAIL + assert_equal JAIL, result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + + @logger.clear + result = @resolver.system_path '/foo', "#{JAIL}/assets/stylesheets", JAIL + assert_equal "#{JAIL}/foo", result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + + @logger.clear + result = @resolver.system_path '/../foo', "#{JAIL}/assets/stylesheets", JAIL + assert_equal "#{JAIL}/foo", result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + + @logger.clear + @resolver.file_separator = '\\' + result = @resolver.system_path 'baz.adoc', 'C:/foo', 'C:/bar' + assert_equal 'C:/bar/baz.adoc', result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' end test 'allows use of absolute target or start if resolved path is sub-path of jail' do assert_equal "#{JAIL}/my/path", @resolver.system_path("#{JAIL}/my/path", '', JAIL) assert_equal "#{JAIL}/my/path", @resolver.system_path("#{JAIL}/my/path", nil, JAIL) assert_equal "#{JAIL}/my/path", @resolver.system_path('', "#{JAIL}/my/path", JAIL) assert_equal "#{JAIL}/my/path", @resolver.system_path(nil, "#{JAIL}/my/path", JAIL) assert_equal "#{JAIL}/my/path", @resolver.system_path('path', "#{JAIL}/my", JAIL) + assert_equal '/foo/bar/baz.adoc', @resolver.system_path('/foo/bar/baz.adoc', nil, '/') + assert_equal '/foo/bar/baz.adoc', @resolver.system_path('baz.adoc', '/foo/bar', '/') + assert_equal '/foo/bar/baz.adoc', @resolver.system_path('baz.adoc', 'foo/bar', '/') end test 'uses jail path if start path is empty' do assert_equal "#{JAIL}/images/tiger.png", @resolver.system_path('images/tiger.png', '', JAIL) assert_equal "#{JAIL}/images/tiger.png", @resolver.system_path('images/tiger.png', nil, JAIL) end - test 'raises security error if start is not contained within jail' do + test 'warns if start is not contained within jail' do + result = @resolver.system_path 'images/tiger.png', '/etc', JAIL + assert_equal %(#{JAIL}/images/tiger.png), result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + + @logger.clear + result = @resolver.system_path '.', '/etc', JAIL + assert_equal JAIL, result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + + @logger.clear + @resolver.file_separator = '\\' + result = @resolver.system_path '.', 'C:/foo', 'C:/bar' + assert_equal 'C:/bar', result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + end + + test 'allows start path to be parent of jail if resolved target is inside jail' do + assert_equal "#{JAIL}/foo/path", @resolver.system_path('foo/path', JAIL, "#{JAIL}/foo") + @resolver.file_separator = '\\' + assert_equal "C:/dev/project/README.adoc", @resolver.system_path('project/README.adoc', 'C:/dev', 'C:/dev/project') + end + + test 'relocates target to jail if resolved value fails outside of jail' do + result = @resolver.system_path 'bar/baz.adoc', JAIL, "#{JAIL}/foo" + assert_equal %(#{JAIL}/foo/bar/baz.adoc), result + assert_message @logger, :WARN, 'path is outside of jail; recovering automatically' + + @logger.clear + @resolver.file_separator = '\\' + result = @resolver.system_path 'bar/baz.adoc', 'D:/', 'C:/foo' + assert_equal 'C:/foo/bar/baz.adoc', result + assert_message @logger, :WARN, '~outside of jail root' + end + + test 'raises security error if start is not contained within jail and recover is disabled' do begin - @resolver.system_path('images/tiger.png', '/etc', JAIL) + @resolver.system_path('images/tiger.png', '/etc', JAIL, :recover => false) flunk 'Expecting SecurityError to be raised' rescue SecurityError end begin - @resolver.system_path('.', '/etc', JAIL) + @resolver.system_path('.', '/etc', JAIL, :recover => false) flunk 'Expecting SecurityError to be raised' rescue SecurityError end end + test 'expands parent references in absolute path if jail is not specified' do + assert_equal '/etc/stylesheet.css', @resolver.system_path('/usr/share/../../etc/stylesheet.css') + end + test 'resolves absolute directory if jail is not specified' do assert_equal '/usr/share/stylesheet.css', @resolver.system_path('/usr/share/stylesheet.css', '/home/dallen/docs/assets/stylesheets') end test 'resolves ancestor directory of start if jail is not specified' do @@ -206,41 +291,38 @@ pwd = File.expand_path(Dir.pwd) assert_equal "#{pwd}/.images/tiger.png", @resolver.system_path('.images/tiger.png', '') assert_equal "#{pwd}/.images/tiger.png", @resolver.system_path('.images/tiger.png', nil) end - test 'resolves and normalizes start with target is empty' do + test 'resolves and normalizes start when target is empty' do pwd = File.expand_path Dir.pwd assert_equal '/home/doctor/docs', (@resolver.system_path '', '/home/doctor/docs') + assert_equal '/home/doctor/docs', (@resolver.system_path '', '/home/doctor/./docs') assert_equal '/home/doctor/docs', (@resolver.system_path nil, '/home/doctor/docs') + assert_equal '/home/doctor/docs', (@resolver.system_path nil, '/home/doctor/./docs') assert_equal %(#{pwd}/assets/images), (@resolver.system_path nil, 'assets/images') - result, warnings = redirect_streams do |_, err| - [(@resolver.system_path '', '../assets/images', JAIL), err.string] - end - assert_equal %(#{JAIL}/assets/images), result - assert_includes warnings, 'path has illegal reference to ancestor of jail' + @resolver.system_path '', '../assets/images', JAIL + assert_message @logger, :WARN, 'path has illegal reference to ancestor of jail; recovering automatically' end test 'posixifies windows paths' do + @resolver.file_separator = '\\' assert_equal "#{JAIL}/assets/css", @resolver.system_path('..\\css', 'assets\\stylesheets', JAIL) end test 'resolves windows paths when file separator is backlash' do @resolver.file_separator = '\\' assert_equal 'C:/data/docs', (@resolver.system_path '..', 'C:\\data\\docs\\assets', 'C:\\data\\docs') - result, warnings = redirect_streams do |_, err| - [(@resolver.system_path '..\\..', 'C:\\data\\docs\\assets', 'C:\\data\\docs'), err.string] - end + result = @resolver.system_path '..\\..', 'C:\\data\\docs\\assets', 'C:\\data\\docs' assert_equal 'C:/data/docs', result - assert_includes warnings, 'path has illegal reference to ancestor of jail' + assert_message @logger, :WARN, 'path has illegal reference to ancestor of jail; recovering automatically' - result, warnings = redirect_streams do |_, err| - [(@resolver.system_path '..\\..\\css', 'C:\\data\\docs\\assets', 'C:\\data\\docs'), err.string] - end + @logger.clear + result = @resolver.system_path '..\\..\\css', 'C:\\data\\docs\\assets', 'C:\\data\\docs' assert_equal 'C:/data/docs/css', result - assert_includes warnings, 'path has illegal reference to ancestor of jail' + assert_message @logger, :WARN, 'path has illegal reference to ancestor of jail; recovering automatically' end test 'should calculate relative path' do filename = @resolver.system_path('part1/chapter1/section1.adoc', nil, JAIL) assert_equal "#{JAIL}/part1/chapter1/section1.adoc", filename