class Chef::Util::PathHelper

Constants

WIN_MAX_PATH

Maximum characters in a standard Windows path (260 including drive letter and NUL)

Public Class Methods

canonical_path(path, add_prefix=true) click to toggle source

Produces a comparable path.

# File lib/chef/util/path_helper.rb, line 68
def self.canonical_path(path, add_prefix=true)
  # Rather than find an equivalent for File.absolute_path on 1.8.7, just bail out
  raise NotImplementedError, "This feature is not supported on Ruby versions < 1.9" if RUBY_VERSION.to_f < 1.9

  # First remove extra separators and resolve any relative paths
  abs_path = File.absolute_path(path)

  if Chef::Platform.windows?
    # Add the \\?\ API prefix on Windows unless add_prefix is false
    # Downcase on Windows where paths are still case-insensitive
    abs_path.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
    if add_prefix && abs_path !~ /^\\?\/
      abs_path.insert(0, "\\\\?\\")
    end

    abs_path.downcase!
  end

  abs_path
end
paths_eql?(path1, path2) click to toggle source
# File lib/chef/util/path_helper.rb, line 89
def self.paths_eql?(path1, path2)
  canonical_path(path1) == canonical_path(path2)
end
printable?(string) click to toggle source
# File lib/chef/util/path_helper.rb, line 57
def self.printable?(string)
  # returns true if string is free of non-printable characters (escape sequences)
  # this returns false for whitespace escape sequences as well, e.g. \n\t
  if string =~ /[^[:print:]]/
    false
  else
    true
  end
end
validate_path(path) click to toggle source
# File lib/chef/util/path_helper.rb, line 28
def self.validate_path(path)
  if Chef::Platform.windows?
    unless printable?(path)
      msg = "Path '#{path}' contains non-printable characters. Check that backslashes are escaped with another backslash (e.g. C:\\\\Windows) in double-quoted strings."
      Chef::Log.error(msg)
      raise Chef::Exceptions::ValidationFailed, msg
    end
      
    if windows_max_length_exceeded?(path)
      Chef::Log.debug("Path '#{path}' is longer than #{WIN_MAX_PATH}, prefixing with'\\\\?\\'")
      path.insert(0, "\\\\?\\")
    end
  end

  path
end
windows_max_length_exceeded?(path) click to toggle source
# File lib/chef/util/path_helper.rb, line 45
def self.windows_max_length_exceeded?(path)
  # Check to see if paths without the \\?\ prefix are over the maximum allowed length for the Windows API
  # http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
  unless path =~ /^\\?\/
    if path.length > WIN_MAX_PATH
      return true
    end
  end
  
  false
end