# # # patch "ChangeLog" # from [88f13e6c2611f4b166a53e62af4ae6a29d9f60f9] # to [b6ae1142671fd4464689a6f7c36ea26b32339327] # # patch "paths.cc" # from [33170c42ef7db7d1205e132558b8a568fa6ac430] # to [16c9c7c98129e61004f883895ceb0c484dfd06a7] # # patch "tests/add_ignores__MTN/__driver__.lua" # from [81778ae3ef791759099c08b779bfbfb0b72a1511] # to [503ec9410da0f3e6c7741488ac7ae89ed10250aa] # # patch "tests/add_inside__MTN_/__driver__.lua" # from [cbecfde7ee32cd40177b011b4461489f2f8960ce] # to [2373896f4d854210a29793dc9631f90423df3717] # # patch "work.cc" # from [6d3bd354fb938e901952cc38599415dbb056e3c8] # to [4f0a072a9021d19c3f695263fe14fc7a9f4446b8] # ============================================================ --- ChangeLog 88f13e6c2611f4b166a53e62af4ae6a29d9f60f9 +++ ChangeLog b6ae1142671fd4464689a6f7c36ea26b32339327 @@ -1,5 +1,20 @@ 2006-12-22 Derek Scherger + * paths.cc (normalize_external_path): factor new function out of + file_path constructor's external path normalization code + (file_path::file_path): call new normalization function for + external paths + (bookkeeping_path::is_bookkeeping_path): normalize strings as + external paths before checking for _MTN prefix + * tests/add_ignores__MTN/__driver__.lua: un-xfail subdir testcase + * tests/add_inside__MTN_/__driver__.lua: add now ignores + bookkeeping paths rather than failing on them. account for this + and check for associated warning on stderr + * work.cc (editable_working_tree::attach_node): add some + whitespace, it's cheap + +2006-12-22 Derek Scherger + * cmd.hh (args_to_paths): warn about bookkeeping paths but ignore them * tests/_MTN_case-folding_security_patch/__driver__.lua: mtn add no longer fails but still reports warnings on stderr ============================================================ --- paths.cc 33170c42ef7db7d1205e132558b8a568fa6ac430 +++ paths.cc 16c9c7c98129e61004f883895ceb0c484dfd06a7 @@ -156,9 +156,9 @@ has_bad_chars(string const & path) return false; } -// fully_normalized_path performs very similar function to file_path.split(). -// if want_split is set, split_path will be filled with the '/' separated -// components of the path. +// fully_normalized_path_split performs very similar function to +// file_path.split(). if want_split is set, split_path will be filled with +// the '/' separated components of the path. static inline bool fully_normalized_path_split(string const & path, bool want_split, split_path & sp) @@ -250,28 +250,22 @@ internal_string_to_split_path(string con I(fully_normalized_path_split(path, true, sp)); } -file_path::file_path(file_path::source_type type, string const & path) +static void +normalize_external_path(string const & path, string & normalized) { - MM(path); - I(utf8_validate(path)); - switch (type) + if (!initial_rel_path.initialized) { - case internal: - data = path; - break; - case external: - if (!initial_rel_path.initialized) - { - // we are not in a workspace; treat this as an internal - // path, and set the access_tracker() into a very uninitialised - // state so that we will hit an exception if we do eventually - // enter a workspace - initial_rel_path.may_not_initialize(); - data = path; - N(is_valid_internal(path) && !in_bookkeeping_dir(path), - F("path '%s' is invalid") % path); - break; - } + // we are not in a workspace; treat this as an internal + // path, and set the access_tracker() into a very uninitialised + // state so that we will hit an exception if we do eventually + // enter a workspace + initial_rel_path.may_not_initialize(); + normalized = path; + N(is_valid_internal(path), + F("path '%s' is invalid") % path); + } + else + { N(!path.empty(), F("empty path '%s' is invalid") % path); fs::path out, base, relative; try @@ -285,12 +279,28 @@ file_path::file_path(file_path::source_t { N(false, F("path '%s' is invalid") % path); } - data = utf8(out.string()); - if (data() == ".") - data = string(""); + normalized = out.string(); + if (normalized == ".") + normalized = string(""); N(!relative.has_root_path(), F("absolute path '%s' is invalid") % relative.string()); - N(fully_normalized_path(data()), F("path '%s' is invalid") % data); + N(fully_normalized_path(normalized), F("path '%s' is invalid") % normalized); + } +} + +file_path::file_path(file_path::source_type type, string const & path) +{ + string normalized; + MM(path); + I(utf8_validate(path)); + switch (type) + { + case internal: + data = path; + break; + case external: + normalize_external_path(path, normalized); + data = utf8(normalized); N(!in_bookkeeping_dir(data()), F("path '%s' is in bookkeeping dir") % data); break; } @@ -308,7 +318,9 @@ bookkeeping_path::is_bookkeeping_path(st bool bookkeeping_path::is_bookkeeping_path(string const & path) { - return in_bookkeeping_dir(path); + string normalized; + normalize_external_path(path, normalized); + return in_bookkeeping_dir(normalized); } /////////////////////////////////////////////////////////////////////////// ============================================================ --- tests/add_ignores__MTN/__driver__.lua 81778ae3ef791759099c08b779bfbfb0b72a1511 +++ tests/add_ignores__MTN/__driver__.lua 503ec9410da0f3e6c7741488ac7ae89ed10250aa @@ -11,4 +11,4 @@ check(mtn("add", "-R", "_MTN", "subdir") check(mtn("add", "-R", "_MTN", "subdir"), 0, false, false) -- simulate shell glob of "../*" from workspace subdir +check(indir("subdir", mtn("add", "-R", "../_MTN", "../subdir")), 0, false, false) -xfail(indir("subdir", mtn("add", "-R", "../_MTN", "../subdir")), 0, false, false) ============================================================ --- tests/add_inside__MTN_/__driver__.lua cbecfde7ee32cd40177b011b4461489f2f8960ce +++ tests/add_inside__MTN_/__driver__.lua 2373896f4d854210a29793dc9631f90423df3717 @@ -1,8 +1,9 @@ writefile("_MTN/testfile2", "blah blah") mtn_setup() writefile("testfile1", "blah blah") writefile("_MTN/testfile2", "blah blah") -check(indir("_MTN", mtn("add", "testfile2")), 1, false, false) +check(indir("_MTN", mtn("add", "testfile2")), 0, false, true) +check(qgrep("testfile2", "stderr")) check(indir("_MTN", mtn("add", "../testfile1")), 0, false, false) ============================================================ --- work.cc 6d3bd354fb938e901952cc38599415dbb056e3c8 +++ work.cc 4f0a072a9021d19c3f695263fe14fc7a9f4446b8 @@ -752,6 +752,7 @@ editable_working_tree::attach_node(node_ } else P(F("adding %s") % dst_pth); + if (dst_pth == file_path()) { // root dir attach, so we move contents, rather than the dir itself