Module: FSDB::PathUtilities
Overview
Extends FSDB:Databases to have methods for validating and normalizing paths, path globbing, directory traversal, making links, …
Defined Under Namespace
Classes: InvalidPathError
Instance Method Summary collapse
-
#canonical(path) ⇒ Object
Attempts to convert a path to a canonical form so that ‘/foo/bar’, ‘foo/bar’, ‘foo//bar’, and ‘foo/zap/../bar’ all result in the same path.
-
#canonical?(path) ⇒ Boolean
Is the path in the simplest, canonical representation?.
-
#directory?(path) ⇒ Boolean
Use this to check whether a path yielded by an iterator is a directory.
-
#glob(str) ⇒ Object
Dir globbing.
-
#valid?(path) ⇒ Boolean
Does the path refer to an object within the database? This doesn’t check for links.
-
#validate(path) ⇒ Object
Raises InvalidPathError if canonical(path) still has embedded ‘..’, which means the path would refer to a file not below the database directory.
Instance Method Details
#canonical(path) ⇒ Object
Attempts to convert a path to a canonical form so that ‘/foo/bar’, ‘foo/bar’, ‘foo//bar’, and ‘foo/zap/../bar’ all result in the same path. The canonical form is the simplest.
Doesn’t remove trailing ‘/’, which indicates directory.
This is not necessary for database access, it’s just for display purposes and for validation.
16 17 18 19 20 21 22 23 |
# File 'lib/fsdb/util.rb', line 16 def canonical(path) path = path.dup while path.gsub!(/[^\/]+\/+\.\.(?=\/)/, ""); end path.gsub!(/\/\/+/, "/") path.gsub!(/\/\.\//, "/") path.sub!(/^\/+/, "") path end |
#canonical?(path) ⇒ Boolean
Is the path in the simplest, canonical representation?
26 27 28 |
# File 'lib/fsdb/util.rb', line 26 def canonical?(path) path == canonical(path) end |
#directory?(path) ⇒ Boolean
Use this to check whether a path yielded by an iterator is a directory.
64 65 66 |
# File 'lib/fsdb/util.rb', line 64 def directory?(path) /\/$/ =~ path end |
#glob(str) ⇒ Object
Dir globbing. Excludes ‘.’ and all ‘..*’ files (but includes ‘../’, if included in the match). Returns sorted array of strings to help avoid deadlock when doing nested transactions. Does not yield to block (as Dir.glob does) because #glob operates under Thread.exclusive, because it uses Dir.chdir, which is not threadsafe.
54 55 56 57 58 59 60 61 |
# File 'lib/fsdb/util.rb', line 54 def glob(str) raise ArgumentError, "Block not supported for #glob" if block_given? Thread.exclusive do Dir.chdir(@dir) do Dir.glob(str).reject { |e| e =~ /(?:^\.$|\.\.[^\/]*$)/ }.sort! end end end |
#valid?(path) ⇒ Boolean
Does the path refer to an object within the database? This doesn’t check for links.
32 33 34 |
# File 'lib/fsdb/util.rb', line 32 def valid?(path) canonical(path) !~ /\.\./ end |
#validate(path) ⇒ Object
Raises InvalidPathError if canonical(path) still has embedded ‘..’, which means the path would refer to a file not below the database directory. Returns the canonical path, otherwise.
41 42 43 44 45 46 47 |
# File 'lib/fsdb/util.rb', line 41 def validate(path) path = canonical(path) unless valid?(path) raise InvalidPathError, "Path #{path} is outside the database." end path end |