lib/prawn/svg/loaders/file.rb in prawn-svg-0.23.0 vs lib/prawn/svg/loaders/file.rb in prawn-svg-0.23.1
- old
+ new
@@ -1,32 +1,58 @@
+#
+# Load a file from disk.
+#
+# WINDOWS
+# =======
+# Windows is supported, but must use URLs in the modern structure like:
+# file:///x:/path/to/the/file.png
+# or as a relative path:
+# directory/file.png
+# or as an absolute path from the current drive:
+# /path/to/the/file.png
+#
+# Ruby's URI parser does not like backslashes, nor can it handle filenames as URLs starting
+# with a drive letter as it thinks you're giving it a scheme.
+#
+# URL ENCODING
+# ============
+# This module assumes the URL that is passed in has been URL-encoded. If for some reason
+# you're passing in a filename that hasn't been taken from an XML document's attribute,
+# you will want to URL encode it before you pass it in.
+#
module Prawn::SVG::Loaders
class File
attr_reader :root_path
def initialize(root_path)
+ if root_path.empty?
+ raise ArgumentError, "An empty string is not a valid root path. Use '.' if you want the current working directory."
+ end
+
@root_path = ::File.expand_path(root_path)
raise ArgumentError, "#{root_path} is not a directory" unless Dir.exist?(@root_path)
end
def from_url(url)
uri = build_uri(url)
if uri && uri.scheme.nil? && uri.path
- path = build_absolute_path(uri.path)
- load_file(path)
+ load_file(uri.path)
elsif uri && uri.scheme == 'file'
assert_valid_file_uri!(uri)
- load_file(uri.path)
+ path = windows? ? fix_windows_path(uri.path) : uri.path
+ load_file(path)
end
end
private
def load_file(path)
- path = ::File.expand_path(path)
+ path = URI.decode(path)
+ path = build_absolute_and_expand_path(path)
assert_valid_path!(path)
assert_file_exists!(path)
IO.read(path)
end
@@ -36,21 +62,21 @@
rescue URI::InvalidURIError
end
end
def assert_valid_path!(path)
- if !path.start_with?("#{root_path}/")
+ # TODO : case sensitive comparison, but it's going to be a bit of a headache
+ # making it dependent on whether the file system is case sensitive or not.
+ # Leaving it like this until it's a problem for someone.
+
+ if !path.start_with?("#{root_path}#{::File::SEPARATOR}")
raise Prawn::SVG::UrlLoader::Error, "file path is not inside the root path of #{root_path}"
end
end
- def build_absolute_path(path)
- if path[0] == "/"
- path
- else
- "#{root_path}/#{path}"
- end
+ def build_absolute_and_expand_path(path)
+ ::File.expand_path(path, root_path)
end
def assert_valid_file_uri!(uri)
if uri.host
raise Prawn::SVG::UrlLoader::Error, "prawn-svg does not suport file: URLs with a host. Your URL probably doesn't start with three slashes, and it should."
@@ -59,8 +85,20 @@
def assert_file_exists!(path)
if !::File.exist?(path)
raise Prawn::SVG::UrlLoader::Error, "File #{path} does not exist"
end
+ end
+
+ def fix_windows_path(path)
+ if matches = path.match(%r(\A/[a-z]:/)i)
+ path[1..-1]
+ else
+ path
+ end
+ end
+
+ def windows?
+ !!(RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
end
end
end