lib/asciidoctor/abstract_node.rb in asciidoctor-0.0.9 vs lib/asciidoctor/abstract_node.rb in asciidoctor-0.1.0

- old
+ new

@@ -95,11 +95,11 @@ # specified icon name. # # If the 'icon' attribute is set on this block, the name is ignored and the # value of this attribute is used as the target image path. Otherwise, # construct a target image path by concatenating the value of the 'iconsdir' - # attribute, the icon name and the value of the 'iconstype' attribute + # attribute, the icon name and the value of the 'icontype' attribute # (defaulting to 'png'). # # The target image path is then passed through the #image_uri() method. If # the 'data-uri' attribute is set on the document, the image will be # safely converted to a data URI. @@ -111,11 +111,11 @@ # Returns A String reference or data URI for an icon image def icon_uri(name) if attr? 'icon' image_uri(attr('icon'), nil) else - image_uri(name + '.' + @document.attr('iconstype', 'png'), 'iconsdir') + image_uri(name + '.' + @document.attr('icontype', 'png'), 'iconsdir') end end # Public: Construct a reference or data URI to the target image. # @@ -164,66 +164,72 @@ image_path = File.join(normalize_asset_path(@document.attr(asset_dir_key, '.'), asset_dir_key), target_image) else image_path = normalize_asset_path(target_image) end - 'data:' + mimetype + ';base64,' + Base64.encode64(IO.read(image_path)).delete("\n") + bindata = nil + if IO.respond_to? :binread + bindata = IO.binread(image_path) + else + bindata = File.open(image_path, 'rb') {|file| file.read } + end + 'data:' + mimetype + ';base64,' + Base64.encode64(bindata).delete("\n") end # Public: Normalize the asset file or directory to a concrete and rinsed path # # The most important functionality in this method is to prevent the asset # reference from resolving to a directory outside of the chroot directory - # (which defaults to the directory of the source file, stored in the 'docdir' - # attribute) if the document safe level is set to SafeMode::SAFE or greater - # (a condition which is true by default). + # (which defaults to the directory of the source file, stored in the base_dir + # instance variable on Document) if the document safe level is set to + # SafeMode::SAFE or greater (a condition which is true by default). # # asset_ref - the String asset file or directory referenced in the document # or configuration attribute # asset_name - the String name of the file or directory being resolved (for use in # the warning message) (default: 'path') # # Examples # # # given these fixtures - # document.attr('docdir') - # # => "/path/to/docdir" + # document.base_dir + # # => "/path/to/chroot" # document.safe >= Asciidoctor::SafeMode::SAFE # # => true # # # then # normalize_asset_path('images') - # # => "/path/to/docdir/images" + # # => "/path/to/chroot/images" # normalize_asset_path('/etc/images') - # # => "/path/to/docdir/images" + # # => "/path/to/chroot/images" # normalize_asset_path('../images') - # # => "/path/to/docdir/images" + # # => "/path/to/chroot/images" # # # given these fixtures - # document.attr('docdir') - # # => "/path/to/docdir" + # document.base_dir + # # => "/path/to/chroot" # document.safe >= Asciidoctor::SafeMode::SAFE # # => false # # # then # normalize_asset_path('images') - # # => "/path/to/docdir/images" + # # => "/path/to/chroot/images" # normalize_asset_path('/etc/images') # # => "/etc/images" # normalize_asset_path('../images') # # => "/path/to/images" # # Returns The normalized asset file or directory as a String path #-- # TODO this method is missing a coordinate; it should be able to resolve # both the directory reference and the path to an asset in it; callers # of this method are still doing a File.join to finish the task - def normalize_asset_path(asset_ref, asset_name = 'path') + def normalize_asset_path(asset_ref, asset_name = 'path', autocorrect = true) # TODO we may use pathname enough to make it a top-level require Asciidoctor.require_library 'pathname' - input_path = File.expand_path(@document.attr('docdir')) + input_path = @document.base_dir asset_path = Pathname.new(asset_ref) if asset_path.relative? asset_path = File.expand_path(File.join(input_path, asset_ref)) else @@ -231,10 +237,14 @@ end if @document.safe >= Asciidoctor::SafeMode::SAFE relative_asset_path = Pathname.new(asset_path).relative_path_from(Pathname.new(input_path)).to_s if relative_asset_path.start_with?('..') - puts 'asciidoctor: WARNING: ' + asset_name + ' has illegal reference to ancestor of base directory' + if autocorrect + puts 'asciidoctor: WARNING: ' + asset_name + ' has illegal reference to ancestor of base directory' + else + raise SecurityError, "#{asset_name} has reference to path outside of base directory, disallowed in safe mode: #{asset_path}" + end relative_asset_path.sub!(/^(?:\.\.\/)*/, '') # just to be absolutely sure ;) if relative_asset_path[0..0] == '.' raise 'Substitution of parent path references failed for ' + relative_asset_path end