1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/files/file_path.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,458 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// FilePath is a container for pathnames stored in a platform's native string 1.9 +// type, providing containers for manipulation in according with the 1.10 +// platform's conventions for pathnames. It supports the following path 1.11 +// types: 1.12 +// 1.13 +// POSIX Windows 1.14 +// --------------- ---------------------------------- 1.15 +// Fundamental type char[] wchar_t[] 1.16 +// Encoding unspecified* UTF-16 1.17 +// Separator / \, tolerant of / 1.18 +// Drive letters no case-insensitive A-Z followed by : 1.19 +// Alternate root // (surprise!) \\, for UNC paths 1.20 +// 1.21 +// * The encoding need not be specified on POSIX systems, although some 1.22 +// POSIX-compliant systems do specify an encoding. Mac OS X uses UTF-8. 1.23 +// Chrome OS also uses UTF-8. 1.24 +// Linux does not specify an encoding, but in practice, the locale's 1.25 +// character set may be used. 1.26 +// 1.27 +// For more arcane bits of path trivia, see below. 1.28 +// 1.29 +// FilePath objects are intended to be used anywhere paths are. An 1.30 +// application may pass FilePath objects around internally, masking the 1.31 +// underlying differences between systems, only differing in implementation 1.32 +// where interfacing directly with the system. For example, a single 1.33 +// OpenFile(const FilePath &) function may be made available, allowing all 1.34 +// callers to operate without regard to the underlying implementation. On 1.35 +// POSIX-like platforms, OpenFile might wrap fopen, and on Windows, it might 1.36 +// wrap _wfopen_s, perhaps both by calling file_path.value().c_str(). This 1.37 +// allows each platform to pass pathnames around without requiring conversions 1.38 +// between encodings, which has an impact on performance, but more imporantly, 1.39 +// has an impact on correctness on platforms that do not have well-defined 1.40 +// encodings for pathnames. 1.41 +// 1.42 +// Several methods are available to perform common operations on a FilePath 1.43 +// object, such as determining the parent directory (DirName), isolating the 1.44 +// final path component (BaseName), and appending a relative pathname string 1.45 +// to an existing FilePath object (Append). These methods are highly 1.46 +// recommended over attempting to split and concatenate strings directly. 1.47 +// These methods are based purely on string manipulation and knowledge of 1.48 +// platform-specific pathname conventions, and do not consult the filesystem 1.49 +// at all, making them safe to use without fear of blocking on I/O operations. 1.50 +// These methods do not function as mutators but instead return distinct 1.51 +// instances of FilePath objects, and are therefore safe to use on const 1.52 +// objects. The objects themselves are safe to share between threads. 1.53 +// 1.54 +// To aid in initialization of FilePath objects from string literals, a 1.55 +// FILE_PATH_LITERAL macro is provided, which accounts for the difference 1.56 +// between char[]-based pathnames on POSIX systems and wchar_t[]-based 1.57 +// pathnames on Windows. 1.58 +// 1.59 +// Paths can't contain NULs as a precaution agaist premature truncation. 1.60 +// 1.61 +// Because a FilePath object should not be instantiated at the global scope, 1.62 +// instead, use a FilePath::CharType[] and initialize it with 1.63 +// FILE_PATH_LITERAL. At runtime, a FilePath object can be created from the 1.64 +// character array. Example: 1.65 +// 1.66 +// | const FilePath::CharType kLogFileName[] = FILE_PATH_LITERAL("log.txt"); 1.67 +// | 1.68 +// | void Function() { 1.69 +// | FilePath log_file_path(kLogFileName); 1.70 +// | [...] 1.71 +// | } 1.72 +// 1.73 +// WARNING: FilePaths should ALWAYS be displayed with LTR directionality, even 1.74 +// when the UI language is RTL. This means you always need to pass filepaths 1.75 +// through base::i18n::WrapPathWithLTRFormatting() before displaying it in the 1.76 +// RTL UI. 1.77 +// 1.78 +// This is a very common source of bugs, please try to keep this in mind. 1.79 +// 1.80 +// ARCANE BITS OF PATH TRIVIA 1.81 +// 1.82 +// - A double leading slash is actually part of the POSIX standard. Systems 1.83 +// are allowed to treat // as an alternate root, as Windows does for UNC 1.84 +// (network share) paths. Most POSIX systems don't do anything special 1.85 +// with two leading slashes, but FilePath handles this case properly 1.86 +// in case it ever comes across such a system. FilePath needs this support 1.87 +// for Windows UNC paths, anyway. 1.88 +// References: 1.89 +// The Open Group Base Specifications Issue 7, sections 3.266 ("Pathname") 1.90 +// and 4.12 ("Pathname Resolution"), available at: 1.91 +// http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_266 1.92 +// http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_12 1.93 +// 1.94 +// - Windows treats c:\\ the same way it treats \\. This was intended to 1.95 +// allow older applications that require drive letters to support UNC paths 1.96 +// like \\server\share\path, by permitting c:\\server\share\path as an 1.97 +// equivalent. Since the OS treats these paths specially, FilePath needs 1.98 +// to do the same. Since Windows can use either / or \ as the separator, 1.99 +// FilePath treats c://, c:\\, //, and \\ all equivalently. 1.100 +// Reference: 1.101 +// The Old New Thing, "Why is a drive letter permitted in front of UNC 1.102 +// paths (sometimes)?", available at: 1.103 +// http://blogs.msdn.com/oldnewthing/archive/2005/11/22/495740.aspx 1.104 + 1.105 +#ifndef BASE_FILES_FILE_PATH_H_ 1.106 +#define BASE_FILES_FILE_PATH_H_ 1.107 + 1.108 +#include <stddef.h> 1.109 +#include <string> 1.110 +#include <vector> 1.111 + 1.112 +#include "base/base_export.h" 1.113 +#include "base/compiler_specific.h" 1.114 +#include "base/containers/hash_tables.h" 1.115 +#include "base/strings/string16.h" 1.116 +#include "base/strings/string_piece.h" // For implicit conversions. 1.117 +#include "build/build_config.h" 1.118 + 1.119 +// Windows-style drive letter support and pathname separator characters can be 1.120 +// enabled and disabled independently, to aid testing. These #defines are 1.121 +// here so that the same setting can be used in both the implementation and 1.122 +// in the unit test. 1.123 +#if defined(OS_WIN) 1.124 +#define FILE_PATH_USES_DRIVE_LETTERS 1.125 +#define FILE_PATH_USES_WIN_SEPARATORS 1.126 +#endif // OS_WIN 1.127 + 1.128 +class Pickle; 1.129 +class PickleIterator; 1.130 + 1.131 +namespace base { 1.132 + 1.133 +// An abstraction to isolate users from the differences between native 1.134 +// pathnames on different platforms. 1.135 +class BASE_EXPORT FilePath { 1.136 + public: 1.137 +#if defined(OS_POSIX) 1.138 + // On most platforms, native pathnames are char arrays, and the encoding 1.139 + // may or may not be specified. On Mac OS X, native pathnames are encoded 1.140 + // in UTF-8. 1.141 + typedef std::string StringType; 1.142 +#elif defined(OS_WIN) 1.143 + // On Windows, for Unicode-aware applications, native pathnames are wchar_t 1.144 + // arrays encoded in UTF-16. 1.145 + typedef std::wstring StringType; 1.146 +#endif // OS_WIN 1.147 + 1.148 + typedef StringType::value_type CharType; 1.149 + 1.150 + // Null-terminated array of separators used to separate components in 1.151 + // hierarchical paths. Each character in this array is a valid separator, 1.152 + // but kSeparators[0] is treated as the canonical separator and will be used 1.153 + // when composing pathnames. 1.154 + static const CharType kSeparators[]; 1.155 + 1.156 + // arraysize(kSeparators). 1.157 + static const size_t kSeparatorsLength; 1.158 + 1.159 + // A special path component meaning "this directory." 1.160 + static const CharType kCurrentDirectory[]; 1.161 + 1.162 + // A special path component meaning "the parent directory." 1.163 + static const CharType kParentDirectory[]; 1.164 + 1.165 + // The character used to identify a file extension. 1.166 + static const CharType kExtensionSeparator; 1.167 + 1.168 + FilePath(); 1.169 + FilePath(const FilePath& that); 1.170 + explicit FilePath(const StringType& path); 1.171 + ~FilePath(); 1.172 + FilePath& operator=(const FilePath& that); 1.173 + 1.174 + bool operator==(const FilePath& that) const; 1.175 + 1.176 + bool operator!=(const FilePath& that) const; 1.177 + 1.178 + // Required for some STL containers and operations 1.179 + bool operator<(const FilePath& that) const { 1.180 + return path_ < that.path_; 1.181 + } 1.182 + 1.183 + const StringType& value() const { return path_; } 1.184 + 1.185 + bool empty() const { return path_.empty(); } 1.186 + 1.187 + void clear() { path_.clear(); } 1.188 + 1.189 + // Returns true if |character| is in kSeparators. 1.190 + static bool IsSeparator(CharType character); 1.191 + 1.192 + // Returns a vector of all of the components of the provided path. It is 1.193 + // equivalent to calling DirName().value() on the path's root component, 1.194 + // and BaseName().value() on each child component. 1.195 + void GetComponents(std::vector<FilePath::StringType>* components) const; 1.196 + 1.197 + // Returns true if this FilePath is a strict parent of the |child|. Absolute 1.198 + // and relative paths are accepted i.e. is /foo parent to /foo/bar and 1.199 + // is foo parent to foo/bar. Does not convert paths to absolute, follow 1.200 + // symlinks or directory navigation (e.g. ".."). A path is *NOT* its own 1.201 + // parent. 1.202 + bool IsParent(const FilePath& child) const; 1.203 + 1.204 + // If IsParent(child) holds, appends to path (if non-NULL) the 1.205 + // relative path to child and returns true. For example, if parent 1.206 + // holds "/Users/johndoe/Library/Application Support", child holds 1.207 + // "/Users/johndoe/Library/Application Support/Google/Chrome/Default", and 1.208 + // *path holds "/Users/johndoe/Library/Caches", then after 1.209 + // parent.AppendRelativePath(child, path) is called *path will hold 1.210 + // "/Users/johndoe/Library/Caches/Google/Chrome/Default". Otherwise, 1.211 + // returns false. 1.212 + bool AppendRelativePath(const FilePath& child, FilePath* path) const; 1.213 + 1.214 + // Returns a FilePath corresponding to the directory containing the path 1.215 + // named by this object, stripping away the file component. If this object 1.216 + // only contains one component, returns a FilePath identifying 1.217 + // kCurrentDirectory. If this object already refers to the root directory, 1.218 + // returns a FilePath identifying the root directory. 1.219 + FilePath DirName() const WARN_UNUSED_RESULT; 1.220 + 1.221 + // Returns a FilePath corresponding to the last path component of this 1.222 + // object, either a file or a directory. If this object already refers to 1.223 + // the root directory, returns a FilePath identifying the root directory; 1.224 + // this is the only situation in which BaseName will return an absolute path. 1.225 + FilePath BaseName() const WARN_UNUSED_RESULT; 1.226 + 1.227 + // Returns ".jpg" for path "C:\pics\jojo.jpg", or an empty string if 1.228 + // the file has no extension. If non-empty, Extension() will always start 1.229 + // with precisely one ".". The following code should always work regardless 1.230 + // of the value of path. 1.231 + // new_path = path.RemoveExtension().value().append(path.Extension()); 1.232 + // ASSERT(new_path == path.value()); 1.233 + // NOTE: this is different from the original file_util implementation which 1.234 + // returned the extension without a leading "." ("jpg" instead of ".jpg") 1.235 + StringType Extension() const; 1.236 + 1.237 + // Returns "C:\pics\jojo" for path "C:\pics\jojo.jpg" 1.238 + // NOTE: this is slightly different from the similar file_util implementation 1.239 + // which returned simply 'jojo'. 1.240 + FilePath RemoveExtension() const WARN_UNUSED_RESULT; 1.241 + 1.242 + // Inserts |suffix| after the file name portion of |path| but before the 1.243 + // extension. Returns "" if BaseName() == "." or "..". 1.244 + // Examples: 1.245 + // path == "C:\pics\jojo.jpg" suffix == " (1)", returns "C:\pics\jojo (1).jpg" 1.246 + // path == "jojo.jpg" suffix == " (1)", returns "jojo (1).jpg" 1.247 + // path == "C:\pics\jojo" suffix == " (1)", returns "C:\pics\jojo (1)" 1.248 + // path == "C:\pics.old\jojo" suffix == " (1)", returns "C:\pics.old\jojo (1)" 1.249 + FilePath InsertBeforeExtension( 1.250 + const StringType& suffix) const WARN_UNUSED_RESULT; 1.251 + FilePath InsertBeforeExtensionASCII( 1.252 + const base::StringPiece& suffix) const WARN_UNUSED_RESULT; 1.253 + 1.254 + // Adds |extension| to |file_name|. Returns the current FilePath if 1.255 + // |extension| is empty. Returns "" if BaseName() == "." or "..". 1.256 + FilePath AddExtension( 1.257 + const StringType& extension) const WARN_UNUSED_RESULT; 1.258 + 1.259 + // Replaces the extension of |file_name| with |extension|. If |file_name| 1.260 + // does not have an extension, then |extension| is added. If |extension| is 1.261 + // empty, then the extension is removed from |file_name|. 1.262 + // Returns "" if BaseName() == "." or "..". 1.263 + FilePath ReplaceExtension( 1.264 + const StringType& extension) const WARN_UNUSED_RESULT; 1.265 + 1.266 + // Returns true if the file path matches the specified extension. The test is 1.267 + // case insensitive. Don't forget the leading period if appropriate. 1.268 + bool MatchesExtension(const StringType& extension) const; 1.269 + 1.270 + // Returns a FilePath by appending a separator and the supplied path 1.271 + // component to this object's path. Append takes care to avoid adding 1.272 + // excessive separators if this object's path already ends with a separator. 1.273 + // If this object's path is kCurrentDirectory, a new FilePath corresponding 1.274 + // only to |component| is returned. |component| must be a relative path; 1.275 + // it is an error to pass an absolute path. 1.276 + FilePath Append(const StringType& component) const WARN_UNUSED_RESULT; 1.277 + FilePath Append(const FilePath& component) const WARN_UNUSED_RESULT; 1.278 + 1.279 + // Although Windows StringType is std::wstring, since the encoding it uses for 1.280 + // paths is well defined, it can handle ASCII path components as well. 1.281 + // Mac uses UTF8, and since ASCII is a subset of that, it works there as well. 1.282 + // On Linux, although it can use any 8-bit encoding for paths, we assume that 1.283 + // ASCII is a valid subset, regardless of the encoding, since many operating 1.284 + // system paths will always be ASCII. 1.285 + FilePath AppendASCII(const base::StringPiece& component) 1.286 + const WARN_UNUSED_RESULT; 1.287 + 1.288 + // Returns true if this FilePath contains an absolute path. On Windows, an 1.289 + // absolute path begins with either a drive letter specification followed by 1.290 + // a separator character, or with two separator characters. On POSIX 1.291 + // platforms, an absolute path begins with a separator character. 1.292 + bool IsAbsolute() const; 1.293 + 1.294 + // Returns true if the patch ends with a path separator character. 1.295 + bool EndsWithSeparator() const WARN_UNUSED_RESULT; 1.296 + 1.297 + // Returns a copy of this FilePath that ends with a trailing separator. If 1.298 + // the input path is empty, an empty FilePath will be returned. 1.299 + FilePath AsEndingWithSeparator() const WARN_UNUSED_RESULT; 1.300 + 1.301 + // Returns a copy of this FilePath that does not end with a trailing 1.302 + // separator. 1.303 + FilePath StripTrailingSeparators() const WARN_UNUSED_RESULT; 1.304 + 1.305 + // Returns true if this FilePath contains any attempt to reference a parent 1.306 + // directory (i.e. has a path component that is ".." 1.307 + bool ReferencesParent() const; 1.308 + 1.309 + // Return a Unicode human-readable version of this path. 1.310 + // Warning: you can *not*, in general, go from a display name back to a real 1.311 + // path. Only use this when displaying paths to users, not just when you 1.312 + // want to stuff a string16 into some other API. 1.313 + string16 LossyDisplayName() const; 1.314 + 1.315 + // Return the path as ASCII, or the empty string if the path is not ASCII. 1.316 + // This should only be used for cases where the FilePath is representing a 1.317 + // known-ASCII filename. 1.318 + std::string MaybeAsASCII() const; 1.319 + 1.320 + // Return the path as UTF-8. 1.321 + // 1.322 + // This function is *unsafe* as there is no way to tell what encoding is 1.323 + // used in file names on POSIX systems other than Mac and Chrome OS, 1.324 + // although UTF-8 is practically used everywhere these days. To mitigate 1.325 + // the encoding issue, this function internally calls 1.326 + // SysNativeMBToWide() on POSIX systems other than Mac and Chrome OS, 1.327 + // per assumption that the current locale's encoding is used in file 1.328 + // names, but this isn't a perfect solution. 1.329 + // 1.330 + // Once it becomes safe to to stop caring about non-UTF-8 file names, 1.331 + // the SysNativeMBToWide() hack will be removed from the code, along 1.332 + // with "Unsafe" in the function name. 1.333 + std::string AsUTF8Unsafe() const; 1.334 + 1.335 + // Similar to AsUTF8Unsafe, but returns UTF-16 instead. 1.336 + string16 AsUTF16Unsafe() const; 1.337 + 1.338 + // Older Chromium code assumes that paths are always wstrings. 1.339 + // This function converts wstrings to FilePaths, and is 1.340 + // useful to smooth porting that old code to the FilePath API. 1.341 + // It has "Hack" its name so people feel bad about using it. 1.342 + // http://code.google.com/p/chromium/issues/detail?id=24672 1.343 + // 1.344 + // If you are trying to be a good citizen and remove these, ask yourself: 1.345 + // - Am I interacting with other Chrome code that deals with files? Then 1.346 + // try to convert the API into using FilePath. 1.347 + // - Am I interacting with OS-native calls? Then use value() to get at an 1.348 + // OS-native string format. 1.349 + // - Am I using well-known file names, like "config.ini"? Then use the 1.350 + // ASCII functions (we require paths to always be supersets of ASCII). 1.351 + // - Am I displaying a string to the user in some UI? Then use the 1.352 + // LossyDisplayName() function, but keep in mind that you can't 1.353 + // ever use the result of that again as a path. 1.354 + static FilePath FromWStringHack(const std::wstring& wstring); 1.355 + 1.356 + // Returns a FilePath object from a path name in UTF-8. This function 1.357 + // should only be used for cases where you are sure that the input 1.358 + // string is UTF-8. 1.359 + // 1.360 + // Like AsUTF8Unsafe(), this function is unsafe. This function 1.361 + // internally calls SysWideToNativeMB() on POSIX systems other than Mac 1.362 + // and Chrome OS, to mitigate the encoding issue. See the comment at 1.363 + // AsUTF8Unsafe() for details. 1.364 + static FilePath FromUTF8Unsafe(const std::string& utf8); 1.365 + 1.366 + // Similar to FromUTF8Unsafe, but accepts UTF-16 instead. 1.367 + static FilePath FromUTF16Unsafe(const string16& utf16); 1.368 + 1.369 + void WriteToPickle(Pickle* pickle) const; 1.370 + bool ReadFromPickle(PickleIterator* iter); 1.371 + 1.372 + // Normalize all path separators to backslash on Windows 1.373 + // (if FILE_PATH_USES_WIN_SEPARATORS is true), or do nothing on POSIX systems. 1.374 + FilePath NormalizePathSeparators() const; 1.375 + 1.376 + // Compare two strings in the same way the file system does. 1.377 + // Note that these always ignore case, even on file systems that are case- 1.378 + // sensitive. If case-sensitive comparison is ever needed, add corresponding 1.379 + // methods here. 1.380 + // The methods are written as a static method so that they can also be used 1.381 + // on parts of a file path, e.g., just the extension. 1.382 + // CompareIgnoreCase() returns -1, 0 or 1 for less-than, equal-to and 1.383 + // greater-than respectively. 1.384 + static int CompareIgnoreCase(const StringType& string1, 1.385 + const StringType& string2); 1.386 + static bool CompareEqualIgnoreCase(const StringType& string1, 1.387 + const StringType& string2) { 1.388 + return CompareIgnoreCase(string1, string2) == 0; 1.389 + } 1.390 + static bool CompareLessIgnoreCase(const StringType& string1, 1.391 + const StringType& string2) { 1.392 + return CompareIgnoreCase(string1, string2) < 0; 1.393 + } 1.394 + 1.395 +#if defined(OS_MACOSX) 1.396 + // Returns the string in the special canonical decomposed form as defined for 1.397 + // HFS, which is close to, but not quite, decomposition form D. See 1.398 + // http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties 1.399 + // for further comments. 1.400 + // Returns the epmty string if the conversion failed. 1.401 + static StringType GetHFSDecomposedForm(const FilePath::StringType& string); 1.402 + 1.403 + // Special UTF-8 version of FastUnicodeCompare. Cf: 1.404 + // http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm 1.405 + // IMPORTANT: The input strings must be in the special HFS decomposed form! 1.406 + // (cf. above GetHFSDecomposedForm method) 1.407 + static int HFSFastUnicodeCompare(const StringType& string1, 1.408 + const StringType& string2); 1.409 +#endif 1.410 + 1.411 + private: 1.412 + // Remove trailing separators from this object. If the path is absolute, it 1.413 + // will never be stripped any more than to refer to the absolute root 1.414 + // directory, so "////" will become "/", not "". A leading pair of 1.415 + // separators is never stripped, to support alternate roots. This is used to 1.416 + // support UNC paths on Windows. 1.417 + void StripTrailingSeparatorsInternal(); 1.418 + 1.419 + StringType path_; 1.420 +}; 1.421 + 1.422 +} // namespace base 1.423 + 1.424 +// This is required by googletest to print a readable output on test failures. 1.425 +BASE_EXPORT extern void PrintTo(const base::FilePath& path, std::ostream* out); 1.426 + 1.427 +// Macros for string literal initialization of FilePath::CharType[], and for 1.428 +// using a FilePath::CharType[] in a printf-style format string. 1.429 +#if defined(OS_POSIX) 1.430 +#define FILE_PATH_LITERAL(x) x 1.431 +#define PRFilePath "s" 1.432 +#define PRFilePathLiteral "%s" 1.433 +#elif defined(OS_WIN) 1.434 +#define FILE_PATH_LITERAL(x) L ## x 1.435 +#define PRFilePath "ls" 1.436 +#define PRFilePathLiteral L"%ls" 1.437 +#endif // OS_WIN 1.438 + 1.439 +// Provide a hash function so that hash_sets and maps can contain FilePath 1.440 +// objects. 1.441 +namespace BASE_HASH_NAMESPACE { 1.442 +#if defined(COMPILER_GCC) 1.443 + 1.444 +template<> 1.445 +struct hash<base::FilePath> { 1.446 + size_t operator()(const base::FilePath& f) const { 1.447 + return hash<base::FilePath::StringType>()(f.value()); 1.448 + } 1.449 +}; 1.450 + 1.451 +#elif defined(COMPILER_MSVC) 1.452 + 1.453 +inline size_t hash_value(const base::FilePath& f) { 1.454 + return hash_value(f.value()); 1.455 +} 1.456 + 1.457 +#endif // COMPILER 1.458 + 1.459 +} // namespace BASE_HASH_NAMESPACE 1.460 + 1.461 +#endif // BASE_FILES_FILE_PATH_H_