1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "build/build_config.h" 6 7 #if defined(OS_WIN) 8 #include <windows.h> 9 #include <shellapi.h> 10 #include <shlobj.h> 11 #include <tchar.h> 12 #include <winioctl.h> 13 #endif 14 15 #include <algorithm> 16 #include <fstream> 17 #include <set> 18 19 #include "base/base_paths.h" 20 #include "base/file_util.h" 21 #include "base/files/file_enumerator.h" 22 #include "base/files/file_path.h" 23 #include "base/files/scoped_temp_dir.h" 24 #include "base/path_service.h" 25 #include "base/strings/utf_string_conversions.h" 26 #include "base/test/test_file_util.h" 27 #include "base/threading/platform_thread.h" 28 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/platform_test.h" 30 31 #if defined(OS_WIN) 32 #include "base/win/scoped_handle.h" 33 #endif 34 35 // This macro helps avoid wrapped lines in the test structs. 36 #define FPL(x) FILE_PATH_LITERAL(x) 37 38 using base::DirectoryExists; 39 using base::FileEnumerator; 40 using base::FilePath; 41 using base::PathIsWritable; 42 using base::TextContentsEqual; 43 44 namespace { 45 46 // To test that file_util::Normalize FilePath() deals with NTFS reparse points 47 // correctly, we need functions to create and delete reparse points. 48 #if defined(OS_WIN) 49 typedef struct _REPARSE_DATA_BUFFER { 50 ULONG ReparseTag; 51 USHORT ReparseDataLength; 52 USHORT Reserved; 53 union { 54 struct { 55 USHORT SubstituteNameOffset; 56 USHORT SubstituteNameLength; 57 USHORT PrintNameOffset; 58 USHORT PrintNameLength; 59 ULONG Flags; 60 WCHAR PathBuffer[1]; 61 } SymbolicLinkReparseBuffer; 62 struct { 63 USHORT SubstituteNameOffset; 64 USHORT SubstituteNameLength; 65 USHORT PrintNameOffset; 66 USHORT PrintNameLength; 67 WCHAR PathBuffer[1]; 68 } MountPointReparseBuffer; 69 struct { 70 UCHAR DataBuffer[1]; 71 } GenericReparseBuffer; 72 }; 73 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 74 75 // Sets a reparse point. |source| will now point to |target|. Returns true if 76 // the call succeeds, false otherwise. 77 bool SetReparsePoint(HANDLE source, const FilePath& target_path) { 78 std::wstring kPathPrefix = L"\\??\\"; 79 std::wstring target_str; 80 // The juction will not work if the target path does not start with \??\ . 81 if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size())) 82 target_str += kPathPrefix; 83 target_str += target_path.value(); 84 const wchar_t* target = target_str.c_str(); 85 USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]); 86 char buffer[2000] = {0}; 87 DWORD returned; 88 89 REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer); 90 91 data->ReparseTag = 0xa0000003; 92 memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2); 93 94 data->MountPointReparseBuffer.SubstituteNameLength = size_target; 95 data->MountPointReparseBuffer.PrintNameOffset = size_target + 2; 96 data->ReparseDataLength = size_target + 4 + 8; 97 98 int data_size = data->ReparseDataLength + 8; 99 100 if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size, 101 NULL, 0, &returned, NULL)) { 102 return false; 103 } 104 return true; 105 } 106 107 // Delete the reparse point referenced by |source|. Returns true if the call 108 // succeeds, false otherwise. 109 bool DeleteReparsePoint(HANDLE source) { 110 DWORD returned; 111 REPARSE_DATA_BUFFER data = {0}; 112 data.ReparseTag = 0xa0000003; 113 if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0, 114 &returned, NULL)) { 115 return false; 116 } 117 return true; 118 } 119 #endif 120 121 #if defined(OS_POSIX) 122 // Provide a simple way to change the permissions bits on |path| in tests. 123 // ASSERT failures will return, but not stop the test. Caller should wrap 124 // calls to this function in ASSERT_NO_FATAL_FAILURE(). 125 void ChangePosixFilePermissions(const FilePath& path, 126 int mode_bits_to_set, 127 int mode_bits_to_clear) { 128 ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear) 129 << "Can't set and clear the same bits."; 130 131 int mode = 0; 132 ASSERT_TRUE(file_util::GetPosixFilePermissions(path, &mode)); 133 mode |= mode_bits_to_set; 134 mode &= ~mode_bits_to_clear; 135 ASSERT_TRUE(file_util::SetPosixFilePermissions(path, mode)); 136 } 137 #endif // defined(OS_POSIX) 138 139 const wchar_t bogus_content[] = L"I'm cannon fodder."; 140 141 const int FILES_AND_DIRECTORIES = 142 FileEnumerator::FILES | FileEnumerator::DIRECTORIES; 143 144 // file_util winds up using autoreleased objects on the Mac, so this needs 145 // to be a PlatformTest 146 class FileUtilTest : public PlatformTest { 147 protected: 148 virtual void SetUp() OVERRIDE { 149 PlatformTest::SetUp(); 150 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 151 } 152 153 base::ScopedTempDir temp_dir_; 154 }; 155 156 // Collects all the results from the given file enumerator, and provides an 157 // interface to query whether a given file is present. 158 class FindResultCollector { 159 public: 160 explicit FindResultCollector(FileEnumerator& enumerator) { 161 FilePath cur_file; 162 while (!(cur_file = enumerator.Next()).value().empty()) { 163 FilePath::StringType path = cur_file.value(); 164 // The file should not be returned twice. 165 EXPECT_TRUE(files_.end() == files_.find(path)) 166 << "Same file returned twice"; 167 168 // Save for later. 169 files_.insert(path); 170 } 171 } 172 173 // Returns true if the enumerator found the file. 174 bool HasFile(const FilePath& file) const { 175 return files_.find(file.value()) != files_.end(); 176 } 177 178 int size() { 179 return static_cast<int>(files_.size()); 180 } 181 182 private: 183 std::set<FilePath::StringType> files_; 184 }; 185 186 // Simple function to dump some text into a new file. 187 void CreateTextFile(const FilePath& filename, 188 const std::wstring& contents) { 189 std::wofstream file; 190 file.open(filename.value().c_str()); 191 ASSERT_TRUE(file.is_open()); 192 file << contents; 193 file.close(); 194 } 195 196 // Simple function to take out some text from a file. 197 std::wstring ReadTextFile(const FilePath& filename) { 198 wchar_t contents[64]; 199 std::wifstream file; 200 file.open(filename.value().c_str()); 201 EXPECT_TRUE(file.is_open()); 202 file.getline(contents, arraysize(contents)); 203 file.close(); 204 return std::wstring(contents); 205 } 206 207 #if defined(OS_WIN) 208 uint64 FileTimeAsUint64(const FILETIME& ft) { 209 ULARGE_INTEGER u; 210 u.LowPart = ft.dwLowDateTime; 211 u.HighPart = ft.dwHighDateTime; 212 return u.QuadPart; 213 } 214 #endif 215 216 const struct append_case { 217 const wchar_t* path; 218 const wchar_t* ending; 219 const wchar_t* result; 220 } append_cases[] = { 221 #if defined(OS_WIN) 222 {L"c:\\colon\\backslash", L"path", L"c:\\colon\\backslash\\path"}, 223 {L"c:\\colon\\backslash\\", L"path", L"c:\\colon\\backslash\\path"}, 224 {L"c:\\colon\\backslash\\\\", L"path", L"c:\\colon\\backslash\\\\path"}, 225 {L"c:\\colon\\backslash\\", L"", L"c:\\colon\\backslash\\"}, 226 {L"c:\\colon\\backslash", L"", L"c:\\colon\\backslash\\"}, 227 {L"", L"path", L"\\path"}, 228 {L"", L"", L"\\"}, 229 #elif defined(OS_POSIX) 230 {L"/foo/bar", L"path", L"/foo/bar/path"}, 231 {L"/foo/bar/", L"path", L"/foo/bar/path"}, 232 {L"/foo/bar//", L"path", L"/foo/bar//path"}, 233 {L"/foo/bar/", L"", L"/foo/bar/"}, 234 {L"/foo/bar", L"", L"/foo/bar/"}, 235 {L"", L"path", L"/path"}, 236 {L"", L"", L"/"}, 237 #endif 238 }; 239 240 static const struct filename_case { 241 const wchar_t* path; 242 const wchar_t* filename; 243 } filename_cases[] = { 244 #if defined(OS_WIN) 245 {L"c:\\colon\\backslash", L"backslash"}, 246 {L"c:\\colon\\backslash\\", L""}, 247 {L"\\\\filename.exe", L"filename.exe"}, 248 {L"filename.exe", L"filename.exe"}, 249 {L"", L""}, 250 {L"\\\\\\", L""}, 251 {L"c:/colon/backslash", L"backslash"}, 252 {L"c:/colon/backslash/", L""}, 253 {L"//////", L""}, 254 {L"///filename.exe", L"filename.exe"}, 255 #elif defined(OS_POSIX) 256 {L"/foo/bar", L"bar"}, 257 {L"/foo/bar/", L""}, 258 {L"/filename.exe", L"filename.exe"}, 259 {L"filename.exe", L"filename.exe"}, 260 {L"", L""}, 261 {L"/", L""}, 262 #endif 263 }; 264 265 // Test finding the file type from a path name 266 static const struct extension_case { 267 const wchar_t* path; 268 const wchar_t* extension; 269 } extension_cases[] = { 270 #if defined(OS_WIN) 271 {L"C:\\colon\\backslash\\filename.extension", L"extension"}, 272 {L"C:\\colon\\backslash\\filename.", L""}, 273 {L"C:\\colon\\backslash\\filename", L""}, 274 {L"C:\\colon\\backslash\\", L""}, 275 {L"C:\\colon\\backslash.\\", L""}, 276 {L"C:\\colon\\backslash\filename.extension.extension2", L"extension2"}, 277 #elif defined(OS_POSIX) 278 {L"/foo/bar/filename.extension", L"extension"}, 279 {L"/foo/bar/filename.", L""}, 280 {L"/foo/bar/filename", L""}, 281 {L"/foo/bar/", L""}, 282 {L"/foo/bar./", L""}, 283 {L"/foo/bar/filename.extension.extension2", L"extension2"}, 284 {L".", L""}, 285 {L"..", L""}, 286 {L"./foo", L""}, 287 {L"./foo.extension", L"extension"}, 288 {L"/foo.extension1/bar.extension2", L"extension2"}, 289 #endif 290 }; 291 292 // Test finding the directory component of a path 293 static const struct dir_case { 294 const wchar_t* full_path; 295 const wchar_t* directory; 296 } dir_cases[] = { 297 #if defined(OS_WIN) 298 {L"C:\\WINDOWS\\system32\\gdi32.dll", L"C:\\WINDOWS\\system32"}, 299 {L"C:\\WINDOWS\\system32\\not_exist_thx_1138", L"C:\\WINDOWS\\system32"}, 300 {L"C:\\WINDOWS\\system32\\", L"C:\\WINDOWS\\system32"}, 301 {L"C:\\WINDOWS\\system32\\\\", L"C:\\WINDOWS\\system32"}, 302 {L"C:\\WINDOWS\\system32", L"C:\\WINDOWS"}, 303 {L"C:\\WINDOWS\\system32.\\", L"C:\\WINDOWS\\system32."}, 304 {L"C:\\", L"C:\\"}, 305 #elif defined(OS_POSIX) 306 {L"/foo/bar/gdi32.dll", L"/foo/bar"}, 307 {L"/foo/bar/not_exist_thx_1138", L"/foo/bar"}, 308 {L"/foo/bar/", L"/foo/bar"}, 309 {L"/foo/bar//", L"/foo/bar"}, 310 {L"/foo/bar", L"/foo"}, 311 {L"/foo/bar./", L"/foo/bar."}, 312 {L"/", L"/"}, 313 {L".", L"."}, 314 {L"..", L"."}, // yes, ".." technically lives in "." 315 #endif 316 }; 317 318 TEST_F(FileUtilTest, FileAndDirectorySize) { 319 // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize 320 // should return 53 bytes. 321 FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt")); 322 CreateTextFile(file_01, L"12345678901234567890"); 323 int64 size_f1 = 0; 324 ASSERT_TRUE(file_util::GetFileSize(file_01, &size_f1)); 325 EXPECT_EQ(20ll, size_f1); 326 327 FilePath subdir_path = temp_dir_.path().Append(FPL("Level2")); 328 file_util::CreateDirectory(subdir_path); 329 330 FilePath file_02 = subdir_path.Append(FPL("The file 02.txt")); 331 CreateTextFile(file_02, L"123456789012345678901234567890"); 332 int64 size_f2 = 0; 333 ASSERT_TRUE(file_util::GetFileSize(file_02, &size_f2)); 334 EXPECT_EQ(30ll, size_f2); 335 336 FilePath subsubdir_path = subdir_path.Append(FPL("Level3")); 337 file_util::CreateDirectory(subsubdir_path); 338 339 FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt")); 340 CreateTextFile(file_03, L"123"); 341 342 int64 computed_size = base::ComputeDirectorySize(temp_dir_.path()); 343 EXPECT_EQ(size_f1 + size_f2 + 3, computed_size); 344 } 345 346 TEST_F(FileUtilTest, NormalizeFilePathBasic) { 347 // Create a directory under the test dir. Because we create it, 348 // we know it is not a link. 349 FilePath file_a_path = temp_dir_.path().Append(FPL("file_a")); 350 FilePath dir_path = temp_dir_.path().Append(FPL("dir")); 351 FilePath file_b_path = dir_path.Append(FPL("file_b")); 352 file_util::CreateDirectory(dir_path); 353 354 FilePath normalized_file_a_path, normalized_file_b_path; 355 ASSERT_FALSE(base::PathExists(file_a_path)); 356 ASSERT_FALSE(file_util::NormalizeFilePath(file_a_path, 357 &normalized_file_a_path)) 358 << "NormalizeFilePath() should fail on nonexistent paths."; 359 360 CreateTextFile(file_a_path, bogus_content); 361 ASSERT_TRUE(base::PathExists(file_a_path)); 362 ASSERT_TRUE(file_util::NormalizeFilePath(file_a_path, 363 &normalized_file_a_path)); 364 365 CreateTextFile(file_b_path, bogus_content); 366 ASSERT_TRUE(base::PathExists(file_b_path)); 367 ASSERT_TRUE(file_util::NormalizeFilePath(file_b_path, 368 &normalized_file_b_path)); 369 370 // Beacuse this test created |dir_path|, we know it is not a link 371 // or junction. So, the real path of the directory holding file a 372 // must be the parent of the path holding file b. 373 ASSERT_TRUE(normalized_file_a_path.DirName() 374 .IsParent(normalized_file_b_path.DirName())); 375 } 376 377 #if defined(OS_WIN) 378 379 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { 380 // Build the following directory structure: 381 // 382 // temp_dir 383 // |-> base_a 384 // | |-> sub_a 385 // | |-> file.txt 386 // | |-> long_name___... (Very long name.) 387 // | |-> sub_long 388 // | |-> deep.txt 389 // |-> base_b 390 // |-> to_sub_a (reparse point to temp_dir\base_a\sub_a) 391 // |-> to_base_b (reparse point to temp_dir\base_b) 392 // |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long) 393 394 FilePath base_a = temp_dir_.path().Append(FPL("base_a")); 395 ASSERT_TRUE(file_util::CreateDirectory(base_a)); 396 397 FilePath sub_a = base_a.Append(FPL("sub_a")); 398 ASSERT_TRUE(file_util::CreateDirectory(sub_a)); 399 400 FilePath file_txt = sub_a.Append(FPL("file.txt")); 401 CreateTextFile(file_txt, bogus_content); 402 403 // Want a directory whose name is long enough to make the path to the file 404 // inside just under MAX_PATH chars. This will be used to test that when 405 // a junction expands to a path over MAX_PATH chars in length, 406 // NormalizeFilePath() fails without crashing. 407 FilePath sub_long_rel(FPL("sub_long")); 408 FilePath deep_txt(FPL("deep.txt")); 409 410 int target_length = MAX_PATH; 411 target_length -= (sub_a.value().length() + 1); // +1 for the sepperator '\'. 412 target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1); 413 // Without making the path a bit shorter, CreateDirectory() fails. 414 // the resulting path is still long enough to hit the failing case in 415 // NormalizePath(). 416 const int kCreateDirLimit = 4; 417 target_length -= kCreateDirLimit; 418 FilePath::StringType long_name_str = FPL("long_name_"); 419 long_name_str.resize(target_length, '_'); 420 421 FilePath long_name = sub_a.Append(FilePath(long_name_str)); 422 FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt); 423 ASSERT_EQ(MAX_PATH - kCreateDirLimit, deep_file.value().length()); 424 425 FilePath sub_long = deep_file.DirName(); 426 ASSERT_TRUE(file_util::CreateDirectory(sub_long)); 427 CreateTextFile(deep_file, bogus_content); 428 429 FilePath base_b = temp_dir_.path().Append(FPL("base_b")); 430 ASSERT_TRUE(file_util::CreateDirectory(base_b)); 431 432 FilePath to_sub_a = base_b.Append(FPL("to_sub_a")); 433 ASSERT_TRUE(file_util::CreateDirectory(to_sub_a)); 434 base::win::ScopedHandle reparse_to_sub_a( 435 ::CreateFile(to_sub_a.value().c_str(), 436 FILE_ALL_ACCESS, 437 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 438 NULL, 439 OPEN_EXISTING, 440 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 441 NULL)); 442 ASSERT_TRUE(reparse_to_sub_a.IsValid()); 443 ASSERT_TRUE(SetReparsePoint(reparse_to_sub_a, sub_a)); 444 445 FilePath to_base_b = base_b.Append(FPL("to_base_b")); 446 ASSERT_TRUE(file_util::CreateDirectory(to_base_b)); 447 base::win::ScopedHandle reparse_to_base_b( 448 ::CreateFile(to_base_b.value().c_str(), 449 FILE_ALL_ACCESS, 450 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 451 NULL, 452 OPEN_EXISTING, 453 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 454 NULL)); 455 ASSERT_TRUE(reparse_to_base_b.IsValid()); 456 ASSERT_TRUE(SetReparsePoint(reparse_to_base_b, base_b)); 457 458 FilePath to_sub_long = base_b.Append(FPL("to_sub_long")); 459 ASSERT_TRUE(file_util::CreateDirectory(to_sub_long)); 460 base::win::ScopedHandle reparse_to_sub_long( 461 ::CreateFile(to_sub_long.value().c_str(), 462 FILE_ALL_ACCESS, 463 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 464 NULL, 465 OPEN_EXISTING, 466 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 467 NULL)); 468 ASSERT_TRUE(reparse_to_sub_long.IsValid()); 469 ASSERT_TRUE(SetReparsePoint(reparse_to_sub_long, sub_long)); 470 471 // Normalize a junction free path: base_a\sub_a\file.txt . 472 FilePath normalized_path; 473 ASSERT_TRUE(file_util::NormalizeFilePath(file_txt, &normalized_path)); 474 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); 475 476 // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude 477 // the junction to_sub_a. 478 ASSERT_TRUE(file_util::NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), 479 &normalized_path)); 480 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); 481 482 // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be 483 // normalized to exclude junctions to_base_b and to_sub_a . 484 ASSERT_TRUE(file_util::NormalizeFilePath(base_b.Append(FPL("to_base_b")) 485 .Append(FPL("to_base_b")) 486 .Append(FPL("to_sub_a")) 487 .Append(FPL("file.txt")), 488 &normalized_path)); 489 ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str()); 490 491 // A long enough path will cause NormalizeFilePath() to fail. Make a long 492 // path using to_base_b many times, and check that paths long enough to fail 493 // do not cause a crash. 494 FilePath long_path = base_b; 495 const int kLengthLimit = MAX_PATH + 200; 496 while (long_path.value().length() <= kLengthLimit) { 497 long_path = long_path.Append(FPL("to_base_b")); 498 } 499 long_path = long_path.Append(FPL("to_sub_a")) 500 .Append(FPL("file.txt")); 501 502 ASSERT_FALSE(file_util::NormalizeFilePath(long_path, &normalized_path)); 503 504 // Normalizing the junction to deep.txt should fail, because the expanded 505 // path to deep.txt is longer than MAX_PATH. 506 ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_long.Append(deep_txt), 507 &normalized_path)); 508 509 // Delete the reparse points, and see that NormalizeFilePath() fails 510 // to traverse them. 511 ASSERT_TRUE(DeleteReparsePoint(reparse_to_sub_a)); 512 ASSERT_TRUE(DeleteReparsePoint(reparse_to_base_b)); 513 ASSERT_TRUE(DeleteReparsePoint(reparse_to_sub_long)); 514 515 ASSERT_FALSE(file_util::NormalizeFilePath(to_sub_a.Append(FPL("file.txt")), 516 &normalized_path)); 517 } 518 519 TEST_F(FileUtilTest, DevicePathToDriveLetter) { 520 // Get a drive letter. 521 std::wstring real_drive_letter = temp_dir_.path().value().substr(0, 2); 522 if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) { 523 LOG(ERROR) << "Can't get a drive letter to test with."; 524 return; 525 } 526 527 // Get the NT style path to that drive. 528 wchar_t device_path[MAX_PATH] = {'\0'}; 529 ASSERT_TRUE( 530 ::QueryDosDevice(real_drive_letter.c_str(), device_path, MAX_PATH)); 531 FilePath actual_device_path(device_path); 532 FilePath win32_path; 533 534 // Run DevicePathToDriveLetterPath() on the NT style path we got from 535 // QueryDosDevice(). Expect the drive letter we started with. 536 ASSERT_TRUE(file_util::DevicePathToDriveLetterPath(actual_device_path, 537 &win32_path)); 538 ASSERT_EQ(real_drive_letter, win32_path.value()); 539 540 // Add some directories to the path. Expect those extra path componenets 541 // to be preserved. 542 FilePath kRelativePath(FPL("dir1\\dir2\\file.txt")); 543 ASSERT_TRUE(file_util::DevicePathToDriveLetterPath( 544 actual_device_path.Append(kRelativePath), 545 &win32_path)); 546 EXPECT_EQ(FilePath(real_drive_letter + L"\\").Append(kRelativePath).value(), 547 win32_path.value()); 548 549 // Deform the real path so that it is invalid by removing the last four 550 // characters. The way windows names devices that are hard disks 551 // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer 552 // than three characters. The only way the truncated string could be a 553 // real drive is if more than 10^3 disks are mounted: 554 // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1 555 // Check that DevicePathToDriveLetterPath fails. 556 int path_length = actual_device_path.value().length(); 557 int new_length = path_length - 4; 558 ASSERT_LT(0, new_length); 559 FilePath prefix_of_real_device_path( 560 actual_device_path.value().substr(0, new_length)); 561 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath( 562 prefix_of_real_device_path, 563 &win32_path)); 564 565 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath( 566 prefix_of_real_device_path.Append(kRelativePath), 567 &win32_path)); 568 569 // Deform the real path so that it is invalid by adding some characters. For 570 // example, if C: maps to \Device\HardDiskVolume8, then we simulate a 571 // request for the drive letter whose native path is 572 // \Device\HardDiskVolume812345 . We assume such a device does not exist, 573 // because drives are numbered in order and mounting 112345 hard disks will 574 // never happen. 575 const FilePath::StringType kExtraChars = FPL("12345"); 576 577 FilePath real_device_path_plus_numbers( 578 actual_device_path.value() + kExtraChars); 579 580 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath( 581 real_device_path_plus_numbers, 582 &win32_path)); 583 584 ASSERT_FALSE(file_util::DevicePathToDriveLetterPath( 585 real_device_path_plus_numbers.Append(kRelativePath), 586 &win32_path)); 587 } 588 589 TEST_F(FileUtilTest, GetPlatformFileInfoForDirectory) { 590 FilePath empty_dir = temp_dir_.path().Append(FPL("gpfi_test")); 591 ASSERT_TRUE(file_util::CreateDirectory(empty_dir)); 592 base::win::ScopedHandle dir( 593 ::CreateFile(empty_dir.value().c_str(), 594 FILE_ALL_ACCESS, 595 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 596 NULL, 597 OPEN_EXISTING, 598 FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory. 599 NULL)); 600 ASSERT_TRUE(dir.IsValid()); 601 base::PlatformFileInfo info; 602 EXPECT_TRUE(base::GetPlatformFileInfo(dir.Get(), &info)); 603 EXPECT_TRUE(info.is_directory); 604 EXPECT_FALSE(info.is_symbolic_link); 605 EXPECT_EQ(0, info.size); 606 } 607 608 TEST_F(FileUtilTest, CreateTemporaryFileInDirLongPathTest) { 609 // Test that CreateTemporaryFileInDir() creates a path and returns a long path 610 // if it is available. This test requires that: 611 // - the filesystem at |temp_dir_| supports long filenames. 612 // - the account has FILE_LIST_DIRECTORY permission for all ancestor 613 // directories of |temp_dir_|. 614 const FilePath::CharType kLongDirName[] = FPL("A long path"); 615 const FilePath::CharType kTestSubDirName[] = FPL("test"); 616 FilePath long_test_dir = temp_dir_.path().Append(kLongDirName); 617 ASSERT_TRUE(file_util::CreateDirectory(long_test_dir)); 618 619 // kLongDirName is not a 8.3 component. So GetShortName() should give us a 620 // different short name. 621 WCHAR path_buffer[MAX_PATH]; 622 DWORD path_buffer_length = GetShortPathName(long_test_dir.value().c_str(), 623 path_buffer, MAX_PATH); 624 ASSERT_LT(path_buffer_length, DWORD(MAX_PATH)); 625 ASSERT_NE(DWORD(0), path_buffer_length); 626 FilePath short_test_dir(path_buffer); 627 ASSERT_STRNE(kLongDirName, short_test_dir.BaseName().value().c_str()); 628 629 FilePath temp_file; 630 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(short_test_dir, &temp_file)); 631 EXPECT_STREQ(kLongDirName, temp_file.DirName().BaseName().value().c_str()); 632 EXPECT_TRUE(base::PathExists(temp_file)); 633 634 // Create a subdirectory of |long_test_dir| and make |long_test_dir| 635 // unreadable. We should still be able to create a temp file in the 636 // subdirectory, but we won't be able to determine the long path for it. This 637 // mimics the environment that some users run where their user profiles reside 638 // in a location where the don't have full access to the higher level 639 // directories. (Note that this assumption is true for NTFS, but not for some 640 // network file systems. E.g. AFS). 641 FilePath access_test_dir = long_test_dir.Append(kTestSubDirName); 642 ASSERT_TRUE(file_util::CreateDirectory(access_test_dir)); 643 file_util::PermissionRestorer long_test_dir_restorer(long_test_dir); 644 ASSERT_TRUE(file_util::MakeFileUnreadable(long_test_dir)); 645 646 // Use the short form of the directory to create a temporary filename. 647 ASSERT_TRUE(file_util::CreateTemporaryFileInDir( 648 short_test_dir.Append(kTestSubDirName), &temp_file)); 649 EXPECT_TRUE(base::PathExists(temp_file)); 650 EXPECT_TRUE(short_test_dir.IsParent(temp_file.DirName())); 651 652 // Check that the long path can't be determined for |temp_file|. 653 path_buffer_length = GetLongPathName(temp_file.value().c_str(), 654 path_buffer, MAX_PATH); 655 EXPECT_EQ(DWORD(0), path_buffer_length); 656 } 657 658 #endif // defined(OS_WIN) 659 660 #if defined(OS_POSIX) 661 662 TEST_F(FileUtilTest, CreateAndReadSymlinks) { 663 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); 664 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); 665 CreateTextFile(link_to, bogus_content); 666 667 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 668 << "Failed to create file symlink."; 669 670 // If we created the link properly, we should be able to read the contents 671 // through it. 672 std::wstring contents = ReadTextFile(link_from); 673 EXPECT_EQ(bogus_content, contents); 674 675 FilePath result; 676 ASSERT_TRUE(file_util::ReadSymbolicLink(link_from, &result)); 677 EXPECT_EQ(link_to.value(), result.value()); 678 679 // Link to a directory. 680 link_from = temp_dir_.path().Append(FPL("from_dir")); 681 link_to = temp_dir_.path().Append(FPL("to_dir")); 682 ASSERT_TRUE(file_util::CreateDirectory(link_to)); 683 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 684 << "Failed to create directory symlink."; 685 686 // Test failures. 687 EXPECT_FALSE(file_util::CreateSymbolicLink(link_to, link_to)); 688 EXPECT_FALSE(file_util::ReadSymbolicLink(link_to, &result)); 689 FilePath missing = temp_dir_.path().Append(FPL("missing")); 690 EXPECT_FALSE(file_util::ReadSymbolicLink(missing, &result)); 691 } 692 693 // The following test of NormalizeFilePath() require that we create a symlink. 694 // This can not be done on Windows before Vista. On Vista, creating a symlink 695 // requires privilege "SeCreateSymbolicLinkPrivilege". 696 // TODO(skerner): Investigate the possibility of giving base_unittests the 697 // privileges required to create a symlink. 698 TEST_F(FileUtilTest, NormalizeFilePathSymlinks) { 699 // Link one file to another. 700 FilePath link_from = temp_dir_.path().Append(FPL("from_file")); 701 FilePath link_to = temp_dir_.path().Append(FPL("to_file")); 702 CreateTextFile(link_to, bogus_content); 703 704 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 705 << "Failed to create file symlink."; 706 707 // Check that NormalizeFilePath sees the link. 708 FilePath normalized_path; 709 ASSERT_TRUE(file_util::NormalizeFilePath(link_from, &normalized_path)); 710 EXPECT_NE(link_from, link_to); 711 EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value()); 712 EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value()); 713 714 // Link to a directory. 715 link_from = temp_dir_.path().Append(FPL("from_dir")); 716 link_to = temp_dir_.path().Append(FPL("to_dir")); 717 ASSERT_TRUE(file_util::CreateDirectory(link_to)); 718 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 719 << "Failed to create directory symlink."; 720 721 EXPECT_FALSE(file_util::NormalizeFilePath(link_from, &normalized_path)) 722 << "Links to directories should return false."; 723 724 // Test that a loop in the links causes NormalizeFilePath() to return false. 725 link_from = temp_dir_.path().Append(FPL("link_a")); 726 link_to = temp_dir_.path().Append(FPL("link_b")); 727 ASSERT_TRUE(file_util::CreateSymbolicLink(link_to, link_from)) 728 << "Failed to create loop symlink a."; 729 ASSERT_TRUE(file_util::CreateSymbolicLink(link_from, link_to)) 730 << "Failed to create loop symlink b."; 731 732 // Infinite loop! 733 EXPECT_FALSE(file_util::NormalizeFilePath(link_from, &normalized_path)); 734 } 735 #endif // defined(OS_POSIX) 736 737 TEST_F(FileUtilTest, DeleteNonExistent) { 738 FilePath non_existent = temp_dir_.path().AppendASCII("bogus_file_dne.foobar"); 739 ASSERT_FALSE(base::PathExists(non_existent)); 740 741 EXPECT_TRUE(base::DeleteFile(non_existent, false)); 742 ASSERT_FALSE(base::PathExists(non_existent)); 743 EXPECT_TRUE(base::DeleteFile(non_existent, true)); 744 ASSERT_FALSE(base::PathExists(non_existent)); 745 } 746 747 TEST_F(FileUtilTest, DeleteFile) { 748 // Create a file 749 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 1.txt")); 750 CreateTextFile(file_name, bogus_content); 751 ASSERT_TRUE(base::PathExists(file_name)); 752 753 // Make sure it's deleted 754 EXPECT_TRUE(base::DeleteFile(file_name, false)); 755 EXPECT_FALSE(base::PathExists(file_name)); 756 757 // Test recursive case, create a new file 758 file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt")); 759 CreateTextFile(file_name, bogus_content); 760 ASSERT_TRUE(base::PathExists(file_name)); 761 762 // Make sure it's deleted 763 EXPECT_TRUE(base::DeleteFile(file_name, true)); 764 EXPECT_FALSE(base::PathExists(file_name)); 765 } 766 767 #if defined(OS_POSIX) 768 TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) { 769 // Create a file. 770 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt")); 771 CreateTextFile(file_name, bogus_content); 772 ASSERT_TRUE(base::PathExists(file_name)); 773 774 // Create a symlink to the file. 775 FilePath file_link = temp_dir_.path().Append("file_link_2"); 776 ASSERT_TRUE(file_util::CreateSymbolicLink(file_name, file_link)) 777 << "Failed to create symlink."; 778 779 // Delete the symbolic link. 780 EXPECT_TRUE(base::DeleteFile(file_link, false)); 781 782 // Make sure original file is not deleted. 783 EXPECT_FALSE(base::PathExists(file_link)); 784 EXPECT_TRUE(base::PathExists(file_name)); 785 } 786 787 TEST_F(FileUtilTest, DeleteSymlinkToNonExistentFile) { 788 // Create a non-existent file path. 789 FilePath non_existent = temp_dir_.path().Append(FPL("Test DeleteFile 3.txt")); 790 EXPECT_FALSE(base::PathExists(non_existent)); 791 792 // Create a symlink to the non-existent file. 793 FilePath file_link = temp_dir_.path().Append("file_link_3"); 794 ASSERT_TRUE(file_util::CreateSymbolicLink(non_existent, file_link)) 795 << "Failed to create symlink."; 796 797 // Make sure the symbolic link is exist. 798 EXPECT_TRUE(file_util::IsLink(file_link)); 799 EXPECT_FALSE(base::PathExists(file_link)); 800 801 // Delete the symbolic link. 802 EXPECT_TRUE(base::DeleteFile(file_link, false)); 803 804 // Make sure the symbolic link is deleted. 805 EXPECT_FALSE(file_util::IsLink(file_link)); 806 } 807 808 TEST_F(FileUtilTest, ChangeFilePermissionsAndRead) { 809 // Create a file path. 810 FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt")); 811 EXPECT_FALSE(base::PathExists(file_name)); 812 813 const std::string kData("hello"); 814 815 int buffer_size = kData.length(); 816 char* buffer = new char[buffer_size]; 817 818 // Write file. 819 EXPECT_EQ(static_cast<int>(kData.length()), 820 file_util::WriteFile(file_name, kData.data(), kData.length())); 821 EXPECT_TRUE(base::PathExists(file_name)); 822 823 // Make sure the file is readable. 824 int32 mode = 0; 825 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode)); 826 EXPECT_TRUE(mode & file_util::FILE_PERMISSION_READ_BY_USER); 827 828 // Get rid of the read permission. 829 EXPECT_TRUE(file_util::SetPosixFilePermissions(file_name, 0u)); 830 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode)); 831 EXPECT_FALSE(mode & file_util::FILE_PERMISSION_READ_BY_USER); 832 // Make sure the file can't be read. 833 EXPECT_EQ(-1, file_util::ReadFile(file_name, buffer, buffer_size)); 834 835 // Give the read permission. 836 EXPECT_TRUE(file_util::SetPosixFilePermissions( 837 file_name, 838 file_util::FILE_PERMISSION_READ_BY_USER)); 839 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode)); 840 EXPECT_TRUE(mode & file_util::FILE_PERMISSION_READ_BY_USER); 841 // Make sure the file can be read. 842 EXPECT_EQ(static_cast<int>(kData.length()), 843 file_util::ReadFile(file_name, buffer, buffer_size)); 844 845 // Delete the file. 846 EXPECT_TRUE(base::DeleteFile(file_name, false)); 847 EXPECT_FALSE(base::PathExists(file_name)); 848 849 delete[] buffer; 850 } 851 852 TEST_F(FileUtilTest, ChangeFilePermissionsAndWrite) { 853 // Create a file path. 854 FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt")); 855 EXPECT_FALSE(base::PathExists(file_name)); 856 857 const std::string kData("hello"); 858 859 // Write file. 860 EXPECT_EQ(static_cast<int>(kData.length()), 861 file_util::WriteFile(file_name, kData.data(), kData.length())); 862 EXPECT_TRUE(base::PathExists(file_name)); 863 864 // Make sure the file is writable. 865 int mode = 0; 866 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode)); 867 EXPECT_TRUE(mode & file_util::FILE_PERMISSION_WRITE_BY_USER); 868 EXPECT_TRUE(PathIsWritable(file_name)); 869 870 // Get rid of the write permission. 871 EXPECT_TRUE(file_util::SetPosixFilePermissions(file_name, 0u)); 872 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode)); 873 EXPECT_FALSE(mode & file_util::FILE_PERMISSION_WRITE_BY_USER); 874 // Make sure the file can't be write. 875 EXPECT_EQ(-1, 876 file_util::WriteFile(file_name, kData.data(), kData.length())); 877 EXPECT_FALSE(PathIsWritable(file_name)); 878 879 // Give read permission. 880 EXPECT_TRUE(file_util::SetPosixFilePermissions( 881 file_name, 882 file_util::FILE_PERMISSION_WRITE_BY_USER)); 883 EXPECT_TRUE(file_util::GetPosixFilePermissions(file_name, &mode)); 884 EXPECT_TRUE(mode & file_util::FILE_PERMISSION_WRITE_BY_USER); 885 // Make sure the file can be write. 886 EXPECT_EQ(static_cast<int>(kData.length()), 887 file_util::WriteFile(file_name, kData.data(), kData.length())); 888 EXPECT_TRUE(PathIsWritable(file_name)); 889 890 // Delete the file. 891 EXPECT_TRUE(base::DeleteFile(file_name, false)); 892 EXPECT_FALSE(base::PathExists(file_name)); 893 } 894 895 TEST_F(FileUtilTest, ChangeDirectoryPermissionsAndEnumerate) { 896 // Create a directory path. 897 FilePath subdir_path = 898 temp_dir_.path().Append(FPL("PermissionTest1")); 899 file_util::CreateDirectory(subdir_path); 900 ASSERT_TRUE(base::PathExists(subdir_path)); 901 902 // Create a dummy file to enumerate. 903 FilePath file_name = subdir_path.Append(FPL("Test Readable File.txt")); 904 EXPECT_FALSE(base::PathExists(file_name)); 905 const std::string kData("hello"); 906 EXPECT_EQ(static_cast<int>(kData.length()), 907 file_util::WriteFile(file_name, kData.data(), kData.length())); 908 EXPECT_TRUE(base::PathExists(file_name)); 909 910 // Make sure the directory has the all permissions. 911 int mode = 0; 912 EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path, &mode)); 913 EXPECT_EQ(file_util::FILE_PERMISSION_USER_MASK, 914 mode & file_util::FILE_PERMISSION_USER_MASK); 915 916 // Get rid of the permissions from the directory. 917 EXPECT_TRUE(file_util::SetPosixFilePermissions(subdir_path, 0u)); 918 EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path, &mode)); 919 EXPECT_FALSE(mode & file_util::FILE_PERMISSION_USER_MASK); 920 921 // Make sure the file in the directory can't be enumerated. 922 FileEnumerator f1(subdir_path, true, FileEnumerator::FILES); 923 EXPECT_TRUE(base::PathExists(subdir_path)); 924 FindResultCollector c1(f1); 925 EXPECT_EQ(c1.size(), 0); 926 EXPECT_FALSE(file_util::GetPosixFilePermissions(file_name, &mode)); 927 928 // Give the permissions to the directory. 929 EXPECT_TRUE(file_util::SetPosixFilePermissions( 930 subdir_path, 931 file_util::FILE_PERMISSION_USER_MASK)); 932 EXPECT_TRUE(file_util::GetPosixFilePermissions(subdir_path, &mode)); 933 EXPECT_EQ(file_util::FILE_PERMISSION_USER_MASK, 934 mode & file_util::FILE_PERMISSION_USER_MASK); 935 936 // Make sure the file in the directory can be enumerated. 937 FileEnumerator f2(subdir_path, true, FileEnumerator::FILES); 938 FindResultCollector c2(f2); 939 EXPECT_TRUE(c2.HasFile(file_name)); 940 EXPECT_EQ(c2.size(), 1); 941 942 // Delete the file. 943 EXPECT_TRUE(base::DeleteFile(subdir_path, true)); 944 EXPECT_FALSE(base::PathExists(subdir_path)); 945 } 946 947 #endif // defined(OS_POSIX) 948 949 #if defined(OS_WIN) 950 // Tests that the Delete function works for wild cards, especially 951 // with the recursion flag. Also coincidentally tests PathExists. 952 // TODO(erikkay): see if anyone's actually using this feature of the API 953 TEST_F(FileUtilTest, DeleteWildCard) { 954 // Create a file and a directory 955 FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt")); 956 CreateTextFile(file_name, bogus_content); 957 ASSERT_TRUE(base::PathExists(file_name)); 958 959 FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir")); 960 file_util::CreateDirectory(subdir_path); 961 ASSERT_TRUE(base::PathExists(subdir_path)); 962 963 // Create the wildcard path 964 FilePath directory_contents = temp_dir_.path(); 965 directory_contents = directory_contents.Append(FPL("*")); 966 967 // Delete non-recursively and check that only the file is deleted 968 EXPECT_TRUE(base::DeleteFile(directory_contents, false)); 969 EXPECT_FALSE(base::PathExists(file_name)); 970 EXPECT_TRUE(base::PathExists(subdir_path)); 971 972 // Delete recursively and make sure all contents are deleted 973 EXPECT_TRUE(base::DeleteFile(directory_contents, true)); 974 EXPECT_FALSE(base::PathExists(file_name)); 975 EXPECT_FALSE(base::PathExists(subdir_path)); 976 } 977 978 // TODO(erikkay): see if anyone's actually using this feature of the API 979 TEST_F(FileUtilTest, DeleteNonExistantWildCard) { 980 // Create a file and a directory 981 FilePath subdir_path = 982 temp_dir_.path().Append(FPL("DeleteNonExistantWildCard")); 983 file_util::CreateDirectory(subdir_path); 984 ASSERT_TRUE(base::PathExists(subdir_path)); 985 986 // Create the wildcard path 987 FilePath directory_contents = subdir_path; 988 directory_contents = directory_contents.Append(FPL("*")); 989 990 // Delete non-recursively and check nothing got deleted 991 EXPECT_TRUE(base::DeleteFile(directory_contents, false)); 992 EXPECT_TRUE(base::PathExists(subdir_path)); 993 994 // Delete recursively and check nothing got deleted 995 EXPECT_TRUE(base::DeleteFile(directory_contents, true)); 996 EXPECT_TRUE(base::PathExists(subdir_path)); 997 } 998 #endif 999 1000 // Tests non-recursive Delete() for a directory. 1001 TEST_F(FileUtilTest, DeleteDirNonRecursive) { 1002 // Create a subdirectory and put a file and two directories inside. 1003 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive")); 1004 file_util::CreateDirectory(test_subdir); 1005 ASSERT_TRUE(base::PathExists(test_subdir)); 1006 1007 FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt")); 1008 CreateTextFile(file_name, bogus_content); 1009 ASSERT_TRUE(base::PathExists(file_name)); 1010 1011 FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1")); 1012 file_util::CreateDirectory(subdir_path1); 1013 ASSERT_TRUE(base::PathExists(subdir_path1)); 1014 1015 FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2")); 1016 file_util::CreateDirectory(subdir_path2); 1017 ASSERT_TRUE(base::PathExists(subdir_path2)); 1018 1019 // Delete non-recursively and check that the empty dir got deleted 1020 EXPECT_TRUE(base::DeleteFile(subdir_path2, false)); 1021 EXPECT_FALSE(base::PathExists(subdir_path2)); 1022 1023 // Delete non-recursively and check that nothing got deleted 1024 EXPECT_FALSE(base::DeleteFile(test_subdir, false)); 1025 EXPECT_TRUE(base::PathExists(test_subdir)); 1026 EXPECT_TRUE(base::PathExists(file_name)); 1027 EXPECT_TRUE(base::PathExists(subdir_path1)); 1028 } 1029 1030 // Tests recursive Delete() for a directory. 1031 TEST_F(FileUtilTest, DeleteDirRecursive) { 1032 // Create a subdirectory and put a file and two directories inside. 1033 FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirRecursive")); 1034 file_util::CreateDirectory(test_subdir); 1035 ASSERT_TRUE(base::PathExists(test_subdir)); 1036 1037 FilePath file_name = test_subdir.Append(FPL("Test DeleteDirRecursive.txt")); 1038 CreateTextFile(file_name, bogus_content); 1039 ASSERT_TRUE(base::PathExists(file_name)); 1040 1041 FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1")); 1042 file_util::CreateDirectory(subdir_path1); 1043 ASSERT_TRUE(base::PathExists(subdir_path1)); 1044 1045 FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2")); 1046 file_util::CreateDirectory(subdir_path2); 1047 ASSERT_TRUE(base::PathExists(subdir_path2)); 1048 1049 // Delete recursively and check that the empty dir got deleted 1050 EXPECT_TRUE(base::DeleteFile(subdir_path2, true)); 1051 EXPECT_FALSE(base::PathExists(subdir_path2)); 1052 1053 // Delete recursively and check that everything got deleted 1054 EXPECT_TRUE(base::DeleteFile(test_subdir, true)); 1055 EXPECT_FALSE(base::PathExists(file_name)); 1056 EXPECT_FALSE(base::PathExists(subdir_path1)); 1057 EXPECT_FALSE(base::PathExists(test_subdir)); 1058 } 1059 1060 TEST_F(FileUtilTest, MoveFileNew) { 1061 // Create a file 1062 FilePath file_name_from = 1063 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 1064 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1065 ASSERT_TRUE(base::PathExists(file_name_from)); 1066 1067 // The destination. 1068 FilePath file_name_to = temp_dir_.path().Append( 1069 FILE_PATH_LITERAL("Move_Test_File_Destination.txt")); 1070 ASSERT_FALSE(base::PathExists(file_name_to)); 1071 1072 EXPECT_TRUE(base::Move(file_name_from, file_name_to)); 1073 1074 // Check everything has been moved. 1075 EXPECT_FALSE(base::PathExists(file_name_from)); 1076 EXPECT_TRUE(base::PathExists(file_name_to)); 1077 } 1078 1079 TEST_F(FileUtilTest, MoveFileExists) { 1080 // Create a file 1081 FilePath file_name_from = 1082 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 1083 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1084 ASSERT_TRUE(base::PathExists(file_name_from)); 1085 1086 // The destination name. 1087 FilePath file_name_to = temp_dir_.path().Append( 1088 FILE_PATH_LITERAL("Move_Test_File_Destination.txt")); 1089 CreateTextFile(file_name_to, L"Old file content"); 1090 ASSERT_TRUE(base::PathExists(file_name_to)); 1091 1092 EXPECT_TRUE(base::Move(file_name_from, file_name_to)); 1093 1094 // Check everything has been moved. 1095 EXPECT_FALSE(base::PathExists(file_name_from)); 1096 EXPECT_TRUE(base::PathExists(file_name_to)); 1097 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to)); 1098 } 1099 1100 TEST_F(FileUtilTest, MoveFileDirExists) { 1101 // Create a file 1102 FilePath file_name_from = 1103 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 1104 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1105 ASSERT_TRUE(base::PathExists(file_name_from)); 1106 1107 // The destination directory 1108 FilePath dir_name_to = 1109 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 1110 file_util::CreateDirectory(dir_name_to); 1111 ASSERT_TRUE(base::PathExists(dir_name_to)); 1112 1113 EXPECT_FALSE(base::Move(file_name_from, dir_name_to)); 1114 } 1115 1116 1117 TEST_F(FileUtilTest, MoveNew) { 1118 // Create a directory 1119 FilePath dir_name_from = 1120 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir")); 1121 file_util::CreateDirectory(dir_name_from); 1122 ASSERT_TRUE(base::PathExists(dir_name_from)); 1123 1124 // Create a file under the directory 1125 FilePath txt_file_name(FILE_PATH_LITERAL("Move_Test_File.txt")); 1126 FilePath file_name_from = dir_name_from.Append(txt_file_name); 1127 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1128 ASSERT_TRUE(base::PathExists(file_name_from)); 1129 1130 // Move the directory. 1131 FilePath dir_name_to = 1132 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_To_Subdir")); 1133 FilePath file_name_to = 1134 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 1135 1136 ASSERT_FALSE(base::PathExists(dir_name_to)); 1137 1138 EXPECT_TRUE(base::Move(dir_name_from, dir_name_to)); 1139 1140 // Check everything has been moved. 1141 EXPECT_FALSE(base::PathExists(dir_name_from)); 1142 EXPECT_FALSE(base::PathExists(file_name_from)); 1143 EXPECT_TRUE(base::PathExists(dir_name_to)); 1144 EXPECT_TRUE(base::PathExists(file_name_to)); 1145 1146 // Test path traversal. 1147 file_name_from = dir_name_to.Append(txt_file_name); 1148 file_name_to = dir_name_to.Append(FILE_PATH_LITERAL("..")); 1149 file_name_to = file_name_to.Append(txt_file_name); 1150 EXPECT_FALSE(base::Move(file_name_from, file_name_to)); 1151 EXPECT_TRUE(base::PathExists(file_name_from)); 1152 EXPECT_FALSE(base::PathExists(file_name_to)); 1153 EXPECT_TRUE(base::internal::MoveUnsafe(file_name_from, file_name_to)); 1154 EXPECT_FALSE(base::PathExists(file_name_from)); 1155 EXPECT_TRUE(base::PathExists(file_name_to)); 1156 } 1157 1158 TEST_F(FileUtilTest, MoveExist) { 1159 // Create a directory 1160 FilePath dir_name_from = 1161 temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir")); 1162 file_util::CreateDirectory(dir_name_from); 1163 ASSERT_TRUE(base::PathExists(dir_name_from)); 1164 1165 // Create a file under the directory 1166 FilePath file_name_from = 1167 dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 1168 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1169 ASSERT_TRUE(base::PathExists(file_name_from)); 1170 1171 // Move the directory 1172 FilePath dir_name_exists = 1173 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 1174 1175 FilePath dir_name_to = 1176 dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir")); 1177 FilePath file_name_to = 1178 dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt")); 1179 1180 // Create the destination directory. 1181 file_util::CreateDirectory(dir_name_exists); 1182 ASSERT_TRUE(base::PathExists(dir_name_exists)); 1183 1184 EXPECT_TRUE(base::Move(dir_name_from, dir_name_to)); 1185 1186 // Check everything has been moved. 1187 EXPECT_FALSE(base::PathExists(dir_name_from)); 1188 EXPECT_FALSE(base::PathExists(file_name_from)); 1189 EXPECT_TRUE(base::PathExists(dir_name_to)); 1190 EXPECT_TRUE(base::PathExists(file_name_to)); 1191 } 1192 1193 TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) { 1194 // Create a directory. 1195 FilePath dir_name_from = 1196 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1197 file_util::CreateDirectory(dir_name_from); 1198 ASSERT_TRUE(base::PathExists(dir_name_from)); 1199 1200 // Create a file under the directory. 1201 FilePath file_name_from = 1202 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1203 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1204 ASSERT_TRUE(base::PathExists(file_name_from)); 1205 1206 // Create a subdirectory. 1207 FilePath subdir_name_from = 1208 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 1209 file_util::CreateDirectory(subdir_name_from); 1210 ASSERT_TRUE(base::PathExists(subdir_name_from)); 1211 1212 // Create a file under the subdirectory. 1213 FilePath file_name2_from = 1214 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1215 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 1216 ASSERT_TRUE(base::PathExists(file_name2_from)); 1217 1218 // Copy the directory recursively. 1219 FilePath dir_name_to = 1220 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 1221 FilePath file_name_to = 1222 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1223 FilePath subdir_name_to = 1224 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 1225 FilePath file_name2_to = 1226 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1227 1228 ASSERT_FALSE(base::PathExists(dir_name_to)); 1229 1230 EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_to, true)); 1231 1232 // Check everything has been copied. 1233 EXPECT_TRUE(base::PathExists(dir_name_from)); 1234 EXPECT_TRUE(base::PathExists(file_name_from)); 1235 EXPECT_TRUE(base::PathExists(subdir_name_from)); 1236 EXPECT_TRUE(base::PathExists(file_name2_from)); 1237 EXPECT_TRUE(base::PathExists(dir_name_to)); 1238 EXPECT_TRUE(base::PathExists(file_name_to)); 1239 EXPECT_TRUE(base::PathExists(subdir_name_to)); 1240 EXPECT_TRUE(base::PathExists(file_name2_to)); 1241 } 1242 1243 TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) { 1244 // Create a directory. 1245 FilePath dir_name_from = 1246 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1247 file_util::CreateDirectory(dir_name_from); 1248 ASSERT_TRUE(base::PathExists(dir_name_from)); 1249 1250 // Create a file under the directory. 1251 FilePath file_name_from = 1252 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1253 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1254 ASSERT_TRUE(base::PathExists(file_name_from)); 1255 1256 // Create a subdirectory. 1257 FilePath subdir_name_from = 1258 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 1259 file_util::CreateDirectory(subdir_name_from); 1260 ASSERT_TRUE(base::PathExists(subdir_name_from)); 1261 1262 // Create a file under the subdirectory. 1263 FilePath file_name2_from = 1264 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1265 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 1266 ASSERT_TRUE(base::PathExists(file_name2_from)); 1267 1268 // Copy the directory recursively. 1269 FilePath dir_name_exists = 1270 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 1271 1272 FilePath dir_name_to = 1273 dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1274 FilePath file_name_to = 1275 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1276 FilePath subdir_name_to = 1277 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 1278 FilePath file_name2_to = 1279 subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1280 1281 // Create the destination directory. 1282 file_util::CreateDirectory(dir_name_exists); 1283 ASSERT_TRUE(base::PathExists(dir_name_exists)); 1284 1285 EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_exists, true)); 1286 1287 // Check everything has been copied. 1288 EXPECT_TRUE(base::PathExists(dir_name_from)); 1289 EXPECT_TRUE(base::PathExists(file_name_from)); 1290 EXPECT_TRUE(base::PathExists(subdir_name_from)); 1291 EXPECT_TRUE(base::PathExists(file_name2_from)); 1292 EXPECT_TRUE(base::PathExists(dir_name_to)); 1293 EXPECT_TRUE(base::PathExists(file_name_to)); 1294 EXPECT_TRUE(base::PathExists(subdir_name_to)); 1295 EXPECT_TRUE(base::PathExists(file_name2_to)); 1296 } 1297 1298 TEST_F(FileUtilTest, CopyDirectoryNew) { 1299 // Create a directory. 1300 FilePath dir_name_from = 1301 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1302 file_util::CreateDirectory(dir_name_from); 1303 ASSERT_TRUE(base::PathExists(dir_name_from)); 1304 1305 // Create a file under the directory. 1306 FilePath file_name_from = 1307 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1308 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1309 ASSERT_TRUE(base::PathExists(file_name_from)); 1310 1311 // Create a subdirectory. 1312 FilePath subdir_name_from = 1313 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 1314 file_util::CreateDirectory(subdir_name_from); 1315 ASSERT_TRUE(base::PathExists(subdir_name_from)); 1316 1317 // Create a file under the subdirectory. 1318 FilePath file_name2_from = 1319 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1320 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 1321 ASSERT_TRUE(base::PathExists(file_name2_from)); 1322 1323 // Copy the directory not recursively. 1324 FilePath dir_name_to = 1325 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 1326 FilePath file_name_to = 1327 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1328 FilePath subdir_name_to = 1329 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 1330 1331 ASSERT_FALSE(base::PathExists(dir_name_to)); 1332 1333 EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_to, false)); 1334 1335 // Check everything has been copied. 1336 EXPECT_TRUE(base::PathExists(dir_name_from)); 1337 EXPECT_TRUE(base::PathExists(file_name_from)); 1338 EXPECT_TRUE(base::PathExists(subdir_name_from)); 1339 EXPECT_TRUE(base::PathExists(file_name2_from)); 1340 EXPECT_TRUE(base::PathExists(dir_name_to)); 1341 EXPECT_TRUE(base::PathExists(file_name_to)); 1342 EXPECT_FALSE(base::PathExists(subdir_name_to)); 1343 } 1344 1345 TEST_F(FileUtilTest, CopyDirectoryExists) { 1346 // Create a directory. 1347 FilePath dir_name_from = 1348 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1349 file_util::CreateDirectory(dir_name_from); 1350 ASSERT_TRUE(base::PathExists(dir_name_from)); 1351 1352 // Create a file under the directory. 1353 FilePath file_name_from = 1354 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1355 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1356 ASSERT_TRUE(base::PathExists(file_name_from)); 1357 1358 // Create a subdirectory. 1359 FilePath subdir_name_from = 1360 dir_name_from.Append(FILE_PATH_LITERAL("Subdir")); 1361 file_util::CreateDirectory(subdir_name_from); 1362 ASSERT_TRUE(base::PathExists(subdir_name_from)); 1363 1364 // Create a file under the subdirectory. 1365 FilePath file_name2_from = 1366 subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1367 CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle"); 1368 ASSERT_TRUE(base::PathExists(file_name2_from)); 1369 1370 // Copy the directory not recursively. 1371 FilePath dir_name_to = 1372 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 1373 FilePath file_name_to = 1374 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1375 FilePath subdir_name_to = 1376 dir_name_to.Append(FILE_PATH_LITERAL("Subdir")); 1377 1378 // Create the destination directory. 1379 file_util::CreateDirectory(dir_name_to); 1380 ASSERT_TRUE(base::PathExists(dir_name_to)); 1381 1382 EXPECT_TRUE(base::CopyDirectory(dir_name_from, dir_name_to, false)); 1383 1384 // Check everything has been copied. 1385 EXPECT_TRUE(base::PathExists(dir_name_from)); 1386 EXPECT_TRUE(base::PathExists(file_name_from)); 1387 EXPECT_TRUE(base::PathExists(subdir_name_from)); 1388 EXPECT_TRUE(base::PathExists(file_name2_from)); 1389 EXPECT_TRUE(base::PathExists(dir_name_to)); 1390 EXPECT_TRUE(base::PathExists(file_name_to)); 1391 EXPECT_FALSE(base::PathExists(subdir_name_to)); 1392 } 1393 1394 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) { 1395 // Create a file 1396 FilePath file_name_from = 1397 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1398 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1399 ASSERT_TRUE(base::PathExists(file_name_from)); 1400 1401 // The destination name 1402 FilePath file_name_to = temp_dir_.path().Append( 1403 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt")); 1404 ASSERT_FALSE(base::PathExists(file_name_to)); 1405 1406 EXPECT_TRUE(base::CopyDirectory(file_name_from, file_name_to, true)); 1407 1408 // Check the has been copied 1409 EXPECT_TRUE(base::PathExists(file_name_to)); 1410 } 1411 1412 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) { 1413 // Create a file 1414 FilePath file_name_from = 1415 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1416 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1417 ASSERT_TRUE(base::PathExists(file_name_from)); 1418 1419 // The destination name 1420 FilePath file_name_to = temp_dir_.path().Append( 1421 FILE_PATH_LITERAL("Copy_Test_File_Destination.txt")); 1422 CreateTextFile(file_name_to, L"Old file content"); 1423 ASSERT_TRUE(base::PathExists(file_name_to)); 1424 1425 EXPECT_TRUE(base::CopyDirectory(file_name_from, file_name_to, true)); 1426 1427 // Check the has been copied 1428 EXPECT_TRUE(base::PathExists(file_name_to)); 1429 EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to)); 1430 } 1431 1432 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) { 1433 // Create a file 1434 FilePath file_name_from = 1435 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1436 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1437 ASSERT_TRUE(base::PathExists(file_name_from)); 1438 1439 // The destination 1440 FilePath dir_name_to = 1441 temp_dir_.path().Append(FILE_PATH_LITERAL("Destination")); 1442 file_util::CreateDirectory(dir_name_to); 1443 ASSERT_TRUE(base::PathExists(dir_name_to)); 1444 FilePath file_name_to = 1445 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1446 1447 EXPECT_TRUE(base::CopyDirectory(file_name_from, dir_name_to, true)); 1448 1449 // Check the has been copied 1450 EXPECT_TRUE(base::PathExists(file_name_to)); 1451 } 1452 1453 TEST_F(FileUtilTest, CopyDirectoryWithTrailingSeparators) { 1454 // Create a directory. 1455 FilePath dir_name_from = 1456 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1457 file_util::CreateDirectory(dir_name_from); 1458 ASSERT_TRUE(base::PathExists(dir_name_from)); 1459 1460 // Create a file under the directory. 1461 FilePath file_name_from = 1462 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1463 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1464 ASSERT_TRUE(base::PathExists(file_name_from)); 1465 1466 // Copy the directory recursively. 1467 FilePath dir_name_to = 1468 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir")); 1469 FilePath file_name_to = 1470 dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1471 1472 // Create from path with trailing separators. 1473 #if defined(OS_WIN) 1474 FilePath from_path = 1475 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\")); 1476 #elif defined (OS_POSIX) 1477 FilePath from_path = 1478 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///")); 1479 #endif 1480 1481 EXPECT_TRUE(base::CopyDirectory(from_path, dir_name_to, true)); 1482 1483 // Check everything has been copied. 1484 EXPECT_TRUE(base::PathExists(dir_name_from)); 1485 EXPECT_TRUE(base::PathExists(file_name_from)); 1486 EXPECT_TRUE(base::PathExists(dir_name_to)); 1487 EXPECT_TRUE(base::PathExists(file_name_to)); 1488 } 1489 1490 TEST_F(FileUtilTest, CopyFile) { 1491 // Create a directory 1492 FilePath dir_name_from = 1493 temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir")); 1494 file_util::CreateDirectory(dir_name_from); 1495 ASSERT_TRUE(base::PathExists(dir_name_from)); 1496 1497 // Create a file under the directory 1498 FilePath file_name_from = 1499 dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt")); 1500 const std::wstring file_contents(L"Gooooooooooooooooooooogle"); 1501 CreateTextFile(file_name_from, file_contents); 1502 ASSERT_TRUE(base::PathExists(file_name_from)); 1503 1504 // Copy the file. 1505 FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt")); 1506 ASSERT_TRUE(base::CopyFile(file_name_from, dest_file)); 1507 1508 // Copy the file to another location using '..' in the path. 1509 FilePath dest_file2(dir_name_from); 1510 dest_file2 = dest_file2.AppendASCII(".."); 1511 dest_file2 = dest_file2.AppendASCII("DestFile.txt"); 1512 ASSERT_FALSE(base::CopyFile(file_name_from, dest_file2)); 1513 ASSERT_TRUE(base::internal::CopyFileUnsafe(file_name_from, dest_file2)); 1514 1515 FilePath dest_file2_test(dir_name_from); 1516 dest_file2_test = dest_file2_test.DirName(); 1517 dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt"); 1518 1519 // Check everything has been copied. 1520 EXPECT_TRUE(base::PathExists(file_name_from)); 1521 EXPECT_TRUE(base::PathExists(dest_file)); 1522 const std::wstring read_contents = ReadTextFile(dest_file); 1523 EXPECT_EQ(file_contents, read_contents); 1524 EXPECT_TRUE(base::PathExists(dest_file2_test)); 1525 EXPECT_TRUE(base::PathExists(dest_file2)); 1526 } 1527 1528 // file_util winds up using autoreleased objects on the Mac, so this needs 1529 // to be a PlatformTest. 1530 typedef PlatformTest ReadOnlyFileUtilTest; 1531 1532 TEST_F(ReadOnlyFileUtilTest, ContentsEqual) { 1533 FilePath data_dir; 1534 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir)); 1535 data_dir = data_dir.AppendASCII("file_util"); 1536 ASSERT_TRUE(base::PathExists(data_dir)); 1537 1538 FilePath original_file = 1539 data_dir.Append(FILE_PATH_LITERAL("original.txt")); 1540 FilePath same_file = 1541 data_dir.Append(FILE_PATH_LITERAL("same.txt")); 1542 FilePath same_length_file = 1543 data_dir.Append(FILE_PATH_LITERAL("same_length.txt")); 1544 FilePath different_file = 1545 data_dir.Append(FILE_PATH_LITERAL("different.txt")); 1546 FilePath different_first_file = 1547 data_dir.Append(FILE_PATH_LITERAL("different_first.txt")); 1548 FilePath different_last_file = 1549 data_dir.Append(FILE_PATH_LITERAL("different_last.txt")); 1550 FilePath empty1_file = 1551 data_dir.Append(FILE_PATH_LITERAL("empty1.txt")); 1552 FilePath empty2_file = 1553 data_dir.Append(FILE_PATH_LITERAL("empty2.txt")); 1554 FilePath shortened_file = 1555 data_dir.Append(FILE_PATH_LITERAL("shortened.txt")); 1556 FilePath binary_file = 1557 data_dir.Append(FILE_PATH_LITERAL("binary_file.bin")); 1558 FilePath binary_file_same = 1559 data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin")); 1560 FilePath binary_file_diff = 1561 data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin")); 1562 1563 EXPECT_TRUE(ContentsEqual(original_file, original_file)); 1564 EXPECT_TRUE(ContentsEqual(original_file, same_file)); 1565 EXPECT_FALSE(ContentsEqual(original_file, same_length_file)); 1566 EXPECT_FALSE(ContentsEqual(original_file, different_file)); 1567 EXPECT_FALSE(ContentsEqual(FilePath(FILE_PATH_LITERAL("bogusname")), 1568 FilePath(FILE_PATH_LITERAL("bogusname")))); 1569 EXPECT_FALSE(ContentsEqual(original_file, different_first_file)); 1570 EXPECT_FALSE(ContentsEqual(original_file, different_last_file)); 1571 EXPECT_TRUE(ContentsEqual(empty1_file, empty2_file)); 1572 EXPECT_FALSE(ContentsEqual(original_file, shortened_file)); 1573 EXPECT_FALSE(ContentsEqual(shortened_file, original_file)); 1574 EXPECT_TRUE(ContentsEqual(binary_file, binary_file_same)); 1575 EXPECT_FALSE(ContentsEqual(binary_file, binary_file_diff)); 1576 } 1577 1578 TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) { 1579 FilePath data_dir; 1580 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir)); 1581 data_dir = data_dir.AppendASCII("file_util"); 1582 ASSERT_TRUE(base::PathExists(data_dir)); 1583 1584 FilePath original_file = 1585 data_dir.Append(FILE_PATH_LITERAL("original.txt")); 1586 FilePath same_file = 1587 data_dir.Append(FILE_PATH_LITERAL("same.txt")); 1588 FilePath crlf_file = 1589 data_dir.Append(FILE_PATH_LITERAL("crlf.txt")); 1590 FilePath shortened_file = 1591 data_dir.Append(FILE_PATH_LITERAL("shortened.txt")); 1592 FilePath different_file = 1593 data_dir.Append(FILE_PATH_LITERAL("different.txt")); 1594 FilePath different_first_file = 1595 data_dir.Append(FILE_PATH_LITERAL("different_first.txt")); 1596 FilePath different_last_file = 1597 data_dir.Append(FILE_PATH_LITERAL("different_last.txt")); 1598 FilePath first1_file = 1599 data_dir.Append(FILE_PATH_LITERAL("first1.txt")); 1600 FilePath first2_file = 1601 data_dir.Append(FILE_PATH_LITERAL("first2.txt")); 1602 FilePath empty1_file = 1603 data_dir.Append(FILE_PATH_LITERAL("empty1.txt")); 1604 FilePath empty2_file = 1605 data_dir.Append(FILE_PATH_LITERAL("empty2.txt")); 1606 FilePath blank_line_file = 1607 data_dir.Append(FILE_PATH_LITERAL("blank_line.txt")); 1608 FilePath blank_line_crlf_file = 1609 data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt")); 1610 1611 EXPECT_TRUE(TextContentsEqual(original_file, same_file)); 1612 EXPECT_TRUE(TextContentsEqual(original_file, crlf_file)); 1613 EXPECT_FALSE(TextContentsEqual(original_file, shortened_file)); 1614 EXPECT_FALSE(TextContentsEqual(original_file, different_file)); 1615 EXPECT_FALSE(TextContentsEqual(original_file, different_first_file)); 1616 EXPECT_FALSE(TextContentsEqual(original_file, different_last_file)); 1617 EXPECT_FALSE(TextContentsEqual(first1_file, first2_file)); 1618 EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file)); 1619 EXPECT_FALSE(TextContentsEqual(original_file, empty1_file)); 1620 EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file)); 1621 } 1622 1623 // We don't need equivalent functionality outside of Windows. 1624 #if defined(OS_WIN) 1625 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) { 1626 // Create a directory 1627 FilePath dir_name_from = 1628 temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir")); 1629 file_util::CreateDirectory(dir_name_from); 1630 ASSERT_TRUE(base::PathExists(dir_name_from)); 1631 1632 // Create a file under the directory 1633 FilePath file_name_from = 1634 dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1635 CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle"); 1636 ASSERT_TRUE(base::PathExists(file_name_from)); 1637 1638 // Move the directory by using CopyAndDeleteDirectory 1639 FilePath dir_name_to = temp_dir_.path().Append( 1640 FILE_PATH_LITERAL("CopyAndDelete_To_Subdir")); 1641 FilePath file_name_to = 1642 dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt")); 1643 1644 ASSERT_FALSE(base::PathExists(dir_name_to)); 1645 1646 EXPECT_TRUE(base::internal::CopyAndDeleteDirectory(dir_name_from, 1647 dir_name_to)); 1648 1649 // Check everything has been moved. 1650 EXPECT_FALSE(base::PathExists(dir_name_from)); 1651 EXPECT_FALSE(base::PathExists(file_name_from)); 1652 EXPECT_TRUE(base::PathExists(dir_name_to)); 1653 EXPECT_TRUE(base::PathExists(file_name_to)); 1654 } 1655 1656 TEST_F(FileUtilTest, GetTempDirTest) { 1657 static const TCHAR* kTmpKey = _T("TMP"); 1658 static const TCHAR* kTmpValues[] = { 1659 _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\") 1660 }; 1661 // Save the original $TMP. 1662 size_t original_tmp_size; 1663 TCHAR* original_tmp; 1664 ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey)); 1665 // original_tmp may be NULL. 1666 1667 for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) { 1668 FilePath path; 1669 ::_tputenv_s(kTmpKey, kTmpValues[i]); 1670 file_util::GetTempDir(&path); 1671 EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] << 1672 " result=" << path.value(); 1673 } 1674 1675 // Restore the original $TMP. 1676 if (original_tmp) { 1677 ::_tputenv_s(kTmpKey, original_tmp); 1678 free(original_tmp); 1679 } else { 1680 ::_tputenv_s(kTmpKey, _T("")); 1681 } 1682 } 1683 #endif // OS_WIN 1684 1685 TEST_F(FileUtilTest, CreateTemporaryFileTest) { 1686 FilePath temp_files[3]; 1687 for (int i = 0; i < 3; i++) { 1688 ASSERT_TRUE(file_util::CreateTemporaryFile(&(temp_files[i]))); 1689 EXPECT_TRUE(base::PathExists(temp_files[i])); 1690 EXPECT_FALSE(DirectoryExists(temp_files[i])); 1691 } 1692 for (int i = 0; i < 3; i++) 1693 EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]); 1694 for (int i = 0; i < 3; i++) 1695 EXPECT_TRUE(base::DeleteFile(temp_files[i], false)); 1696 } 1697 1698 TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) { 1699 FilePath names[3]; 1700 FILE* fps[3]; 1701 int i; 1702 1703 // Create; make sure they are open and exist. 1704 for (i = 0; i < 3; ++i) { 1705 fps[i] = file_util::CreateAndOpenTemporaryFile(&(names[i])); 1706 ASSERT_TRUE(fps[i]); 1707 EXPECT_TRUE(base::PathExists(names[i])); 1708 } 1709 1710 // Make sure all names are unique. 1711 for (i = 0; i < 3; ++i) { 1712 EXPECT_FALSE(names[i] == names[(i+1)%3]); 1713 } 1714 1715 // Close and delete. 1716 for (i = 0; i < 3; ++i) { 1717 EXPECT_TRUE(file_util::CloseFile(fps[i])); 1718 EXPECT_TRUE(base::DeleteFile(names[i], false)); 1719 } 1720 } 1721 1722 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) { 1723 FilePath temp_dir; 1724 ASSERT_TRUE(file_util::CreateNewTempDirectory(FilePath::StringType(), 1725 &temp_dir)); 1726 EXPECT_TRUE(base::PathExists(temp_dir)); 1727 EXPECT_TRUE(base::DeleteFile(temp_dir, false)); 1728 } 1729 1730 TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) { 1731 FilePath new_dir; 1732 ASSERT_TRUE(file_util::CreateTemporaryDirInDir( 1733 temp_dir_.path(), 1734 FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"), 1735 &new_dir)); 1736 EXPECT_TRUE(base::PathExists(new_dir)); 1737 EXPECT_TRUE(temp_dir_.path().IsParent(new_dir)); 1738 EXPECT_TRUE(base::DeleteFile(new_dir, false)); 1739 } 1740 1741 TEST_F(FileUtilTest, GetShmemTempDirTest) { 1742 FilePath dir; 1743 EXPECT_TRUE(file_util::GetShmemTempDir(&dir, false)); 1744 EXPECT_TRUE(DirectoryExists(dir)); 1745 } 1746 1747 TEST_F(FileUtilTest, CreateDirectoryTest) { 1748 FilePath test_root = 1749 temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); 1750 #if defined(OS_WIN) 1751 FilePath test_path = 1752 test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\")); 1753 #elif defined(OS_POSIX) 1754 FilePath test_path = 1755 test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/")); 1756 #endif 1757 1758 EXPECT_FALSE(base::PathExists(test_path)); 1759 EXPECT_TRUE(file_util::CreateDirectory(test_path)); 1760 EXPECT_TRUE(base::PathExists(test_path)); 1761 // CreateDirectory returns true if the DirectoryExists returns true. 1762 EXPECT_TRUE(file_util::CreateDirectory(test_path)); 1763 1764 // Doesn't work to create it on top of a non-dir 1765 test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt")); 1766 EXPECT_FALSE(base::PathExists(test_path)); 1767 CreateTextFile(test_path, L"test file"); 1768 EXPECT_TRUE(base::PathExists(test_path)); 1769 EXPECT_FALSE(file_util::CreateDirectory(test_path)); 1770 1771 EXPECT_TRUE(base::DeleteFile(test_root, true)); 1772 EXPECT_FALSE(base::PathExists(test_root)); 1773 EXPECT_FALSE(base::PathExists(test_path)); 1774 1775 // Verify assumptions made by the Windows implementation: 1776 // 1. The current directory always exists. 1777 // 2. The root directory always exists. 1778 ASSERT_TRUE(DirectoryExists(FilePath(FilePath::kCurrentDirectory))); 1779 FilePath top_level = test_root; 1780 while (top_level != top_level.DirName()) { 1781 top_level = top_level.DirName(); 1782 } 1783 ASSERT_TRUE(DirectoryExists(top_level)); 1784 1785 // Given these assumptions hold, it should be safe to 1786 // test that "creating" these directories succeeds. 1787 EXPECT_TRUE(file_util::CreateDirectory( 1788 FilePath(FilePath::kCurrentDirectory))); 1789 EXPECT_TRUE(file_util::CreateDirectory(top_level)); 1790 1791 #if defined(OS_WIN) 1792 FilePath invalid_drive(FILE_PATH_LITERAL("o:\\")); 1793 FilePath invalid_path = 1794 invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir")); 1795 if (!base::PathExists(invalid_drive)) { 1796 EXPECT_FALSE(file_util::CreateDirectory(invalid_path)); 1797 } 1798 #endif 1799 } 1800 1801 TEST_F(FileUtilTest, DetectDirectoryTest) { 1802 // Check a directory 1803 FilePath test_root = 1804 temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test")); 1805 EXPECT_FALSE(base::PathExists(test_root)); 1806 EXPECT_TRUE(file_util::CreateDirectory(test_root)); 1807 EXPECT_TRUE(base::PathExists(test_root)); 1808 EXPECT_TRUE(DirectoryExists(test_root)); 1809 // Check a file 1810 FilePath test_path = 1811 test_root.Append(FILE_PATH_LITERAL("foobar.txt")); 1812 EXPECT_FALSE(base::PathExists(test_path)); 1813 CreateTextFile(test_path, L"test file"); 1814 EXPECT_TRUE(base::PathExists(test_path)); 1815 EXPECT_FALSE(DirectoryExists(test_path)); 1816 EXPECT_TRUE(base::DeleteFile(test_path, false)); 1817 1818 EXPECT_TRUE(base::DeleteFile(test_root, true)); 1819 } 1820 1821 TEST_F(FileUtilTest, FileEnumeratorTest) { 1822 // Test an empty directory. 1823 FileEnumerator f0(temp_dir_.path(), true, FILES_AND_DIRECTORIES); 1824 EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL("")); 1825 EXPECT_EQ(f0.Next().value(), FILE_PATH_LITERAL("")); 1826 1827 // Test an empty directory, non-recursively, including "..". 1828 FileEnumerator f0_dotdot(temp_dir_.path(), false, 1829 FILES_AND_DIRECTORIES | FileEnumerator::INCLUDE_DOT_DOT); 1830 EXPECT_EQ(temp_dir_.path().Append(FILE_PATH_LITERAL("..")).value(), 1831 f0_dotdot.Next().value()); 1832 EXPECT_EQ(FILE_PATH_LITERAL(""), 1833 f0_dotdot.Next().value()); 1834 1835 // create the directories 1836 FilePath dir1 = temp_dir_.path().Append(FILE_PATH_LITERAL("dir1")); 1837 EXPECT_TRUE(file_util::CreateDirectory(dir1)); 1838 FilePath dir2 = temp_dir_.path().Append(FILE_PATH_LITERAL("dir2")); 1839 EXPECT_TRUE(file_util::CreateDirectory(dir2)); 1840 FilePath dir2inner = dir2.Append(FILE_PATH_LITERAL("inner")); 1841 EXPECT_TRUE(file_util::CreateDirectory(dir2inner)); 1842 1843 // create the files 1844 FilePath dir2file = dir2.Append(FILE_PATH_LITERAL("dir2file.txt")); 1845 CreateTextFile(dir2file, std::wstring()); 1846 FilePath dir2innerfile = dir2inner.Append(FILE_PATH_LITERAL("innerfile.txt")); 1847 CreateTextFile(dir2innerfile, std::wstring()); 1848 FilePath file1 = temp_dir_.path().Append(FILE_PATH_LITERAL("file1.txt")); 1849 CreateTextFile(file1, std::wstring()); 1850 FilePath file2_rel = dir2.Append(FilePath::kParentDirectory) 1851 .Append(FILE_PATH_LITERAL("file2.txt")); 1852 CreateTextFile(file2_rel, std::wstring()); 1853 FilePath file2_abs = temp_dir_.path().Append(FILE_PATH_LITERAL("file2.txt")); 1854 1855 // Only enumerate files. 1856 FileEnumerator f1(temp_dir_.path(), true, FileEnumerator::FILES); 1857 FindResultCollector c1(f1); 1858 EXPECT_TRUE(c1.HasFile(file1)); 1859 EXPECT_TRUE(c1.HasFile(file2_abs)); 1860 EXPECT_TRUE(c1.HasFile(dir2file)); 1861 EXPECT_TRUE(c1.HasFile(dir2innerfile)); 1862 EXPECT_EQ(c1.size(), 4); 1863 1864 // Only enumerate directories. 1865 FileEnumerator f2(temp_dir_.path(), true, FileEnumerator::DIRECTORIES); 1866 FindResultCollector c2(f2); 1867 EXPECT_TRUE(c2.HasFile(dir1)); 1868 EXPECT_TRUE(c2.HasFile(dir2)); 1869 EXPECT_TRUE(c2.HasFile(dir2inner)); 1870 EXPECT_EQ(c2.size(), 3); 1871 1872 // Only enumerate directories non-recursively. 1873 FileEnumerator f2_non_recursive( 1874 temp_dir_.path(), false, FileEnumerator::DIRECTORIES); 1875 FindResultCollector c2_non_recursive(f2_non_recursive); 1876 EXPECT_TRUE(c2_non_recursive.HasFile(dir1)); 1877 EXPECT_TRUE(c2_non_recursive.HasFile(dir2)); 1878 EXPECT_EQ(c2_non_recursive.size(), 2); 1879 1880 // Only enumerate directories, non-recursively, including "..". 1881 FileEnumerator f2_dotdot(temp_dir_.path(), false, 1882 FileEnumerator::DIRECTORIES | 1883 FileEnumerator::INCLUDE_DOT_DOT); 1884 FindResultCollector c2_dotdot(f2_dotdot); 1885 EXPECT_TRUE(c2_dotdot.HasFile(dir1)); 1886 EXPECT_TRUE(c2_dotdot.HasFile(dir2)); 1887 EXPECT_TRUE(c2_dotdot.HasFile( 1888 temp_dir_.path().Append(FILE_PATH_LITERAL("..")))); 1889 EXPECT_EQ(c2_dotdot.size(), 3); 1890 1891 // Enumerate files and directories. 1892 FileEnumerator f3(temp_dir_.path(), true, FILES_AND_DIRECTORIES); 1893 FindResultCollector c3(f3); 1894 EXPECT_TRUE(c3.HasFile(dir1)); 1895 EXPECT_TRUE(c3.HasFile(dir2)); 1896 EXPECT_TRUE(c3.HasFile(file1)); 1897 EXPECT_TRUE(c3.HasFile(file2_abs)); 1898 EXPECT_TRUE(c3.HasFile(dir2file)); 1899 EXPECT_TRUE(c3.HasFile(dir2inner)); 1900 EXPECT_TRUE(c3.HasFile(dir2innerfile)); 1901 EXPECT_EQ(c3.size(), 7); 1902 1903 // Non-recursive operation. 1904 FileEnumerator f4(temp_dir_.path(), false, FILES_AND_DIRECTORIES); 1905 FindResultCollector c4(f4); 1906 EXPECT_TRUE(c4.HasFile(dir2)); 1907 EXPECT_TRUE(c4.HasFile(dir2)); 1908 EXPECT_TRUE(c4.HasFile(file1)); 1909 EXPECT_TRUE(c4.HasFile(file2_abs)); 1910 EXPECT_EQ(c4.size(), 4); 1911 1912 // Enumerate with a pattern. 1913 FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, 1914 FILE_PATH_LITERAL("dir*")); 1915 FindResultCollector c5(f5); 1916 EXPECT_TRUE(c5.HasFile(dir1)); 1917 EXPECT_TRUE(c5.HasFile(dir2)); 1918 EXPECT_TRUE(c5.HasFile(dir2file)); 1919 EXPECT_TRUE(c5.HasFile(dir2inner)); 1920 EXPECT_TRUE(c5.HasFile(dir2innerfile)); 1921 EXPECT_EQ(c5.size(), 5); 1922 1923 // Make sure the destructor closes the find handle while in the middle of a 1924 // query to allow TearDown to delete the directory. 1925 FileEnumerator f6(temp_dir_.path(), true, FILES_AND_DIRECTORIES); 1926 EXPECT_FALSE(f6.Next().value().empty()); // Should have found something 1927 // (we don't care what). 1928 } 1929 1930 TEST_F(FileUtilTest, AppendToFile) { 1931 FilePath data_dir = 1932 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); 1933 1934 // Create a fresh, empty copy of this directory. 1935 if (base::PathExists(data_dir)) { 1936 ASSERT_TRUE(base::DeleteFile(data_dir, true)); 1937 } 1938 ASSERT_TRUE(file_util::CreateDirectory(data_dir)); 1939 1940 // Create a fresh, empty copy of this directory. 1941 if (base::PathExists(data_dir)) { 1942 ASSERT_TRUE(base::DeleteFile(data_dir, true)); 1943 } 1944 ASSERT_TRUE(file_util::CreateDirectory(data_dir)); 1945 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt"))); 1946 1947 std::string data("hello"); 1948 EXPECT_EQ(-1, file_util::AppendToFile(foobar, data.c_str(), data.length())); 1949 EXPECT_EQ(static_cast<int>(data.length()), 1950 file_util::WriteFile(foobar, data.c_str(), data.length())); 1951 EXPECT_EQ(static_cast<int>(data.length()), 1952 file_util::AppendToFile(foobar, data.c_str(), data.length())); 1953 1954 const std::wstring read_content = ReadTextFile(foobar); 1955 EXPECT_EQ(L"hellohello", read_content); 1956 } 1957 1958 TEST_F(FileUtilTest, TouchFile) { 1959 FilePath data_dir = 1960 temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); 1961 1962 // Create a fresh, empty copy of this directory. 1963 if (base::PathExists(data_dir)) { 1964 ASSERT_TRUE(base::DeleteFile(data_dir, true)); 1965 } 1966 ASSERT_TRUE(file_util::CreateDirectory(data_dir)); 1967 1968 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt"))); 1969 std::string data("hello"); 1970 ASSERT_TRUE(file_util::WriteFile(foobar, data.c_str(), data.length())); 1971 1972 base::Time access_time; 1973 // This timestamp is divisible by one day (in local timezone), 1974 // to make it work on FAT too. 1975 ASSERT_TRUE(base::Time::FromString("Wed, 16 Nov 1994, 00:00:00", 1976 &access_time)); 1977 1978 base::Time modification_time; 1979 // Note that this timestamp is divisible by two (seconds) - FAT stores 1980 // modification times with 2s resolution. 1981 ASSERT_TRUE(base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", 1982 &modification_time)); 1983 1984 ASSERT_TRUE(file_util::TouchFile(foobar, access_time, modification_time)); 1985 base::PlatformFileInfo file_info; 1986 ASSERT_TRUE(file_util::GetFileInfo(foobar, &file_info)); 1987 EXPECT_EQ(file_info.last_accessed.ToInternalValue(), 1988 access_time.ToInternalValue()); 1989 EXPECT_EQ(file_info.last_modified.ToInternalValue(), 1990 modification_time.ToInternalValue()); 1991 } 1992 1993 TEST_F(FileUtilTest, IsDirectoryEmpty) { 1994 FilePath empty_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("EmptyDir")); 1995 1996 ASSERT_FALSE(base::PathExists(empty_dir)); 1997 1998 ASSERT_TRUE(file_util::CreateDirectory(empty_dir)); 1999 2000 EXPECT_TRUE(file_util::IsDirectoryEmpty(empty_dir)); 2001 2002 FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt"))); 2003 std::string bar("baz"); 2004 ASSERT_TRUE(file_util::WriteFile(foo, bar.c_str(), bar.length())); 2005 2006 EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir)); 2007 } 2008 2009 #if defined(OS_POSIX) 2010 2011 // Testing VerifyPathControlledByAdmin() is hard, because there is no 2012 // way a test can make a file owned by root, or change file paths 2013 // at the root of the file system. VerifyPathControlledByAdmin() 2014 // is implemented as a call to VerifyPathControlledByUser, which gives 2015 // us the ability to test with paths under the test's temp directory, 2016 // using a user id we control. 2017 // Pull tests of VerifyPathControlledByUserTest() into a separate test class 2018 // with a common SetUp() method. 2019 class VerifyPathControlledByUserTest : public FileUtilTest { 2020 protected: 2021 virtual void SetUp() OVERRIDE { 2022 FileUtilTest::SetUp(); 2023 2024 // Create a basic structure used by each test. 2025 // base_dir_ 2026 // |-> sub_dir_ 2027 // |-> text_file_ 2028 2029 base_dir_ = temp_dir_.path().AppendASCII("base_dir"); 2030 ASSERT_TRUE(file_util::CreateDirectory(base_dir_)); 2031 2032 sub_dir_ = base_dir_.AppendASCII("sub_dir"); 2033 ASSERT_TRUE(file_util::CreateDirectory(sub_dir_)); 2034 2035 text_file_ = sub_dir_.AppendASCII("file.txt"); 2036 CreateTextFile(text_file_, L"This text file has some text in it."); 2037 2038 // Get the user and group files are created with from |base_dir_|. 2039 struct stat stat_buf; 2040 ASSERT_EQ(0, stat(base_dir_.value().c_str(), &stat_buf)); 2041 uid_ = stat_buf.st_uid; 2042 ok_gids_.insert(stat_buf.st_gid); 2043 bad_gids_.insert(stat_buf.st_gid + 1); 2044 2045 ASSERT_EQ(uid_, getuid()); // This process should be the owner. 2046 2047 // To ensure that umask settings do not cause the initial state 2048 // of permissions to be different from what we expect, explicitly 2049 // set permissions on the directories we create. 2050 // Make all files and directories non-world-writable. 2051 2052 // Users and group can read, write, traverse 2053 int enabled_permissions = 2054 file_util::FILE_PERMISSION_USER_MASK | 2055 file_util::FILE_PERMISSION_GROUP_MASK; 2056 // Other users can't read, write, traverse 2057 int disabled_permissions = 2058 file_util::FILE_PERMISSION_OTHERS_MASK; 2059 2060 ASSERT_NO_FATAL_FAILURE( 2061 ChangePosixFilePermissions( 2062 base_dir_, enabled_permissions, disabled_permissions)); 2063 ASSERT_NO_FATAL_FAILURE( 2064 ChangePosixFilePermissions( 2065 sub_dir_, enabled_permissions, disabled_permissions)); 2066 } 2067 2068 FilePath base_dir_; 2069 FilePath sub_dir_; 2070 FilePath text_file_; 2071 uid_t uid_; 2072 2073 std::set<gid_t> ok_gids_; 2074 std::set<gid_t> bad_gids_; 2075 }; 2076 2077 TEST_F(VerifyPathControlledByUserTest, BadPaths) { 2078 // File does not exist. 2079 FilePath does_not_exist = base_dir_.AppendASCII("does") 2080 .AppendASCII("not") 2081 .AppendASCII("exist"); 2082 EXPECT_FALSE( 2083 file_util::VerifyPathControlledByUser( 2084 base_dir_, does_not_exist, uid_, ok_gids_)); 2085 2086 // |base| not a subpath of |path|. 2087 EXPECT_FALSE( 2088 file_util::VerifyPathControlledByUser( 2089 sub_dir_, base_dir_, uid_, ok_gids_)); 2090 2091 // An empty base path will fail to be a prefix for any path. 2092 FilePath empty; 2093 EXPECT_FALSE( 2094 file_util::VerifyPathControlledByUser( 2095 empty, base_dir_, uid_, ok_gids_)); 2096 2097 // Finding that a bad call fails proves nothing unless a good call succeeds. 2098 EXPECT_TRUE( 2099 file_util::VerifyPathControlledByUser( 2100 base_dir_, sub_dir_, uid_, ok_gids_)); 2101 } 2102 2103 TEST_F(VerifyPathControlledByUserTest, Symlinks) { 2104 // Symlinks in the path should cause failure. 2105 2106 // Symlink to the file at the end of the path. 2107 FilePath file_link = base_dir_.AppendASCII("file_link"); 2108 ASSERT_TRUE(file_util::CreateSymbolicLink(text_file_, file_link)) 2109 << "Failed to create symlink."; 2110 2111 EXPECT_FALSE( 2112 file_util::VerifyPathControlledByUser( 2113 base_dir_, file_link, uid_, ok_gids_)); 2114 EXPECT_FALSE( 2115 file_util::VerifyPathControlledByUser( 2116 file_link, file_link, uid_, ok_gids_)); 2117 2118 // Symlink from one directory to another within the path. 2119 FilePath link_to_sub_dir = base_dir_.AppendASCII("link_to_sub_dir"); 2120 ASSERT_TRUE(file_util::CreateSymbolicLink(sub_dir_, link_to_sub_dir)) 2121 << "Failed to create symlink."; 2122 2123 FilePath file_path_with_link = link_to_sub_dir.AppendASCII("file.txt"); 2124 ASSERT_TRUE(base::PathExists(file_path_with_link)); 2125 2126 EXPECT_FALSE( 2127 file_util::VerifyPathControlledByUser( 2128 base_dir_, file_path_with_link, uid_, ok_gids_)); 2129 2130 EXPECT_FALSE( 2131 file_util::VerifyPathControlledByUser( 2132 link_to_sub_dir, file_path_with_link, uid_, ok_gids_)); 2133 2134 // Symlinks in parents of base path are allowed. 2135 EXPECT_TRUE( 2136 file_util::VerifyPathControlledByUser( 2137 file_path_with_link, file_path_with_link, uid_, ok_gids_)); 2138 } 2139 2140 TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) { 2141 // Get a uid that is not the uid of files we create. 2142 uid_t bad_uid = uid_ + 1; 2143 2144 // Make all files and directories non-world-writable. 2145 ASSERT_NO_FATAL_FAILURE( 2146 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); 2147 ASSERT_NO_FATAL_FAILURE( 2148 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); 2149 ASSERT_NO_FATAL_FAILURE( 2150 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); 2151 2152 // We control these paths. 2153 EXPECT_TRUE( 2154 file_util::VerifyPathControlledByUser( 2155 base_dir_, sub_dir_, uid_, ok_gids_)); 2156 EXPECT_TRUE( 2157 file_util::VerifyPathControlledByUser( 2158 base_dir_, text_file_, uid_, ok_gids_)); 2159 EXPECT_TRUE( 2160 file_util::VerifyPathControlledByUser( 2161 sub_dir_, text_file_, uid_, ok_gids_)); 2162 2163 // Another user does not control these paths. 2164 EXPECT_FALSE( 2165 file_util::VerifyPathControlledByUser( 2166 base_dir_, sub_dir_, bad_uid, ok_gids_)); 2167 EXPECT_FALSE( 2168 file_util::VerifyPathControlledByUser( 2169 base_dir_, text_file_, bad_uid, ok_gids_)); 2170 EXPECT_FALSE( 2171 file_util::VerifyPathControlledByUser( 2172 sub_dir_, text_file_, bad_uid, ok_gids_)); 2173 2174 // Another group does not control the paths. 2175 EXPECT_FALSE( 2176 file_util::VerifyPathControlledByUser( 2177 base_dir_, sub_dir_, uid_, bad_gids_)); 2178 EXPECT_FALSE( 2179 file_util::VerifyPathControlledByUser( 2180 base_dir_, text_file_, uid_, bad_gids_)); 2181 EXPECT_FALSE( 2182 file_util::VerifyPathControlledByUser( 2183 sub_dir_, text_file_, uid_, bad_gids_)); 2184 } 2185 2186 TEST_F(VerifyPathControlledByUserTest, GroupWriteTest) { 2187 // Make all files and directories writable only by their owner. 2188 ASSERT_NO_FATAL_FAILURE( 2189 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH|S_IWGRP)); 2190 ASSERT_NO_FATAL_FAILURE( 2191 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH|S_IWGRP)); 2192 ASSERT_NO_FATAL_FAILURE( 2193 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH|S_IWGRP)); 2194 2195 // Any group is okay because the path is not group-writable. 2196 EXPECT_TRUE( 2197 file_util::VerifyPathControlledByUser( 2198 base_dir_, sub_dir_, uid_, ok_gids_)); 2199 EXPECT_TRUE( 2200 file_util::VerifyPathControlledByUser( 2201 base_dir_, text_file_, uid_, ok_gids_)); 2202 EXPECT_TRUE( 2203 file_util::VerifyPathControlledByUser( 2204 sub_dir_, text_file_, uid_, ok_gids_)); 2205 2206 EXPECT_TRUE( 2207 file_util::VerifyPathControlledByUser( 2208 base_dir_, sub_dir_, uid_, bad_gids_)); 2209 EXPECT_TRUE( 2210 file_util::VerifyPathControlledByUser( 2211 base_dir_, text_file_, uid_, bad_gids_)); 2212 EXPECT_TRUE( 2213 file_util::VerifyPathControlledByUser( 2214 sub_dir_, text_file_, uid_, bad_gids_)); 2215 2216 // No group is okay, because we don't check the group 2217 // if no group can write. 2218 std::set<gid_t> no_gids; // Empty set of gids. 2219 EXPECT_TRUE( 2220 file_util::VerifyPathControlledByUser( 2221 base_dir_, sub_dir_, uid_, no_gids)); 2222 EXPECT_TRUE( 2223 file_util::VerifyPathControlledByUser( 2224 base_dir_, text_file_, uid_, no_gids)); 2225 EXPECT_TRUE( 2226 file_util::VerifyPathControlledByUser( 2227 sub_dir_, text_file_, uid_, no_gids)); 2228 2229 2230 // Make all files and directories writable by their group. 2231 ASSERT_NO_FATAL_FAILURE( 2232 ChangePosixFilePermissions(base_dir_, S_IWGRP, 0u)); 2233 ASSERT_NO_FATAL_FAILURE( 2234 ChangePosixFilePermissions(sub_dir_, S_IWGRP, 0u)); 2235 ASSERT_NO_FATAL_FAILURE( 2236 ChangePosixFilePermissions(text_file_, S_IWGRP, 0u)); 2237 2238 // Now |ok_gids_| works, but |bad_gids_| fails. 2239 EXPECT_TRUE( 2240 file_util::VerifyPathControlledByUser( 2241 base_dir_, sub_dir_, uid_, ok_gids_)); 2242 EXPECT_TRUE( 2243 file_util::VerifyPathControlledByUser( 2244 base_dir_, text_file_, uid_, ok_gids_)); 2245 EXPECT_TRUE( 2246 file_util::VerifyPathControlledByUser( 2247 sub_dir_, text_file_, uid_, ok_gids_)); 2248 2249 EXPECT_FALSE( 2250 file_util::VerifyPathControlledByUser( 2251 base_dir_, sub_dir_, uid_, bad_gids_)); 2252 EXPECT_FALSE( 2253 file_util::VerifyPathControlledByUser( 2254 base_dir_, text_file_, uid_, bad_gids_)); 2255 EXPECT_FALSE( 2256 file_util::VerifyPathControlledByUser( 2257 sub_dir_, text_file_, uid_, bad_gids_)); 2258 2259 // Because any group in the group set is allowed, 2260 // the union of good and bad gids passes. 2261 2262 std::set<gid_t> multiple_gids; 2263 std::set_union( 2264 ok_gids_.begin(), ok_gids_.end(), 2265 bad_gids_.begin(), bad_gids_.end(), 2266 std::inserter(multiple_gids, multiple_gids.begin())); 2267 2268 EXPECT_TRUE( 2269 file_util::VerifyPathControlledByUser( 2270 base_dir_, sub_dir_, uid_, multiple_gids)); 2271 EXPECT_TRUE( 2272 file_util::VerifyPathControlledByUser( 2273 base_dir_, text_file_, uid_, multiple_gids)); 2274 EXPECT_TRUE( 2275 file_util::VerifyPathControlledByUser( 2276 sub_dir_, text_file_, uid_, multiple_gids)); 2277 } 2278 2279 TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) { 2280 // Make all files and directories non-world-writable. 2281 ASSERT_NO_FATAL_FAILURE( 2282 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); 2283 ASSERT_NO_FATAL_FAILURE( 2284 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); 2285 ASSERT_NO_FATAL_FAILURE( 2286 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); 2287 2288 // Initialy, we control all parts of the path. 2289 EXPECT_TRUE( 2290 file_util::VerifyPathControlledByUser( 2291 base_dir_, sub_dir_, uid_, ok_gids_)); 2292 EXPECT_TRUE( 2293 file_util::VerifyPathControlledByUser( 2294 base_dir_, text_file_, uid_, ok_gids_)); 2295 EXPECT_TRUE( 2296 file_util::VerifyPathControlledByUser( 2297 sub_dir_, text_file_, uid_, ok_gids_)); 2298 2299 // Make base_dir_ world-writable. 2300 ASSERT_NO_FATAL_FAILURE( 2301 ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u)); 2302 EXPECT_FALSE( 2303 file_util::VerifyPathControlledByUser( 2304 base_dir_, sub_dir_, uid_, ok_gids_)); 2305 EXPECT_FALSE( 2306 file_util::VerifyPathControlledByUser( 2307 base_dir_, text_file_, uid_, ok_gids_)); 2308 EXPECT_TRUE( 2309 file_util::VerifyPathControlledByUser( 2310 sub_dir_, text_file_, uid_, ok_gids_)); 2311 2312 // Make sub_dir_ world writable. 2313 ASSERT_NO_FATAL_FAILURE( 2314 ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u)); 2315 EXPECT_FALSE( 2316 file_util::VerifyPathControlledByUser( 2317 base_dir_, sub_dir_, uid_, ok_gids_)); 2318 EXPECT_FALSE( 2319 file_util::VerifyPathControlledByUser( 2320 base_dir_, text_file_, uid_, ok_gids_)); 2321 EXPECT_FALSE( 2322 file_util::VerifyPathControlledByUser( 2323 sub_dir_, text_file_, uid_, ok_gids_)); 2324 2325 // Make text_file_ world writable. 2326 ASSERT_NO_FATAL_FAILURE( 2327 ChangePosixFilePermissions(text_file_, S_IWOTH, 0u)); 2328 EXPECT_FALSE( 2329 file_util::VerifyPathControlledByUser( 2330 base_dir_, sub_dir_, uid_, ok_gids_)); 2331 EXPECT_FALSE( 2332 file_util::VerifyPathControlledByUser( 2333 base_dir_, text_file_, uid_, ok_gids_)); 2334 EXPECT_FALSE( 2335 file_util::VerifyPathControlledByUser( 2336 sub_dir_, text_file_, uid_, ok_gids_)); 2337 2338 // Make sub_dir_ non-world writable. 2339 ASSERT_NO_FATAL_FAILURE( 2340 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); 2341 EXPECT_FALSE( 2342 file_util::VerifyPathControlledByUser( 2343 base_dir_, sub_dir_, uid_, ok_gids_)); 2344 EXPECT_FALSE( 2345 file_util::VerifyPathControlledByUser( 2346 base_dir_, text_file_, uid_, ok_gids_)); 2347 EXPECT_FALSE( 2348 file_util::VerifyPathControlledByUser( 2349 sub_dir_, text_file_, uid_, ok_gids_)); 2350 2351 // Make base_dir_ non-world-writable. 2352 ASSERT_NO_FATAL_FAILURE( 2353 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); 2354 EXPECT_TRUE( 2355 file_util::VerifyPathControlledByUser( 2356 base_dir_, sub_dir_, uid_, ok_gids_)); 2357 EXPECT_FALSE( 2358 file_util::VerifyPathControlledByUser( 2359 base_dir_, text_file_, uid_, ok_gids_)); 2360 EXPECT_FALSE( 2361 file_util::VerifyPathControlledByUser( 2362 sub_dir_, text_file_, uid_, ok_gids_)); 2363 2364 // Back to the initial state: Nothing is writable, so every path 2365 // should pass. 2366 ASSERT_NO_FATAL_FAILURE( 2367 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); 2368 EXPECT_TRUE( 2369 file_util::VerifyPathControlledByUser( 2370 base_dir_, sub_dir_, uid_, ok_gids_)); 2371 EXPECT_TRUE( 2372 file_util::VerifyPathControlledByUser( 2373 base_dir_, text_file_, uid_, ok_gids_)); 2374 EXPECT_TRUE( 2375 file_util::VerifyPathControlledByUser( 2376 sub_dir_, text_file_, uid_, ok_gids_)); 2377 } 2378 2379 #endif // defined(OS_POSIX) 2380 2381 } // namespace 2382