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