# # patch "ChangeLog" # from [db6bbb22aece4e1191dfe6c2dc8d878aeb3f70fb] # to [09fc1962e328b98b40e53a69fd715d68265279ff] # # patch "paths.cc" # from [0c1b0fce8ee57dfbde149d134ddfee6e7d00f508] # to [323736ebeb967accea41ef853150771414055d66] # # patch "paths.hh" # from [a5933d4a31d23da57b3c29ca13570ccc37c85918] # to [ae48a5f399ef3c5e157acbce535415fca6b67715] # ======================================================================== --- ChangeLog db6bbb22aece4e1191dfe6c2dc8d878aeb3f70fb +++ ChangeLog 09fc1962e328b98b40e53a69fd715d68265279ff @@ -1,3 +1,9 @@ +2005-08-23 Nathaniel Smith
+ + * paths.{cc,hh} (fully_normalized_path): Implement. + (external_path): Rename to system_path. + Misc. other updates. + 2005-08-20 Nathaniel Smith * paths.cc (is_absolute): New function. ======================================================================== --- paths.cc 0c1b0fce8ee57dfbde149d134ddfee6e7d00f508 +++ paths.cc 323736ebeb967accea41ef853150771414055d66 @@ -1,3 +1,9 @@ +// copyright (C) 2005 nathaniel smith +// all rights reserved. +// licensed to the public under the terms of the GNU GPL (>= 2) +// see the file COPYING for details + +#include "constants.hh" #include "paths.hh" #include "platform.hh" #include "sanity.hh" @@ -15,8 +21,14 @@ // string with no trailing /. static std::string path_prefix; +#ifdef _WIN32 +static const bool is_win32 = true; +#else +static const bool is_win32 = false; +#endif + bool -find_and_go_to_working_copy(external_path const & search_root) +find_and_go_to_working_copy(system_path const & search_root) { // unimplemented // should do what find_working_copy in file_io.cc does, and what @@ -42,12 +54,100 @@ return false; } -///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// verifying that internal paths are indeed normalized. +// this code must be superfast +/////////////////////////////////////////////////////////////////////////// + +// normalized means: +// -- / as path separator +// -- not an absolute path (on either posix or win32) +// operationally, this means: first character != '/', first character != '\', +// second character != ':' +// -- no illegal characters +// -- 0x00 -- 0x1f, 0x7f, \ are the illegal characters. \ is illegal +// unconditionally to prevent people checking in files on posix that +// have a different interpretation on win32 +// -- (may want to allow 0x0a and 0x0d (LF and CR) in the future, but this +// is blocked on manifest format changing) +// (also requires changes to 'automate inventory', possibly others, to +// handle quoting) +// -- no doubled /'s +// -- no trailing / +// -- no "." or ".." path components +static inline bool +bad_component(std::string const & component) +{ + if (component == "") + return true; + if (component == ".") + return true; + if (component == "..") + return true; + return false; +} + +static inline bool +fully_normalized_path(std::string const & path) +{ + // FIXME: probably should make this a 256-byte static lookup table + const static std::string bad_chars = std::string("\\") + constants::illegal_path_bytes + std::string(1, '\0'); + + // empty path is fine + if (path.empty()) + return true; + // : in second position => absolute path on windows + if (path.size() > 1 && path[1] == ':') + return false; + // first scan for completely illegal bytes + for (std::string::const_iterator i = path.begin(); i != path.end(); ++i) + if (bad_chars.find(*i) != std::string::npos) + return false; + // now check each component + std::string::size_type start, stop; + start = 0; + while (1) + { + stop = path.find('/', start); + if (stop == std::string::npos) + { + if (bad_component(path.substr(start))) + return false; + break; + } + if (bad_component(path.substr(start, stop - start))) + return false; + start = stop + 1; + } +} + +static inline bool +in_bookkeeping_dir(std::string const & path) +{ + return (path.size() < 3) || (path.substr(0, 3) != "MT/"); +} + +file_path::file_path(file_path::source_type type, std::string const & path) +{ + switch source_type + { + internal: + I(fully_normalized_path(path)); + I(!in_bookkeeping_dir(path)); + data = path; + break; + external: + std::string tmp; + normalize_path( + } +} + +/////////////////////////////////////////////////////////////////////////// // splitting/joining // this code must be superfast // it depends very much on knowing that it can only be applied to fully // normalized, relative, paths. -///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// static interner