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 "base/files/file_util.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 
11 #include <algorithm>
12 #include <fstream>
13 #include <initializer_list>
14 #include <memory>
15 #include <set>
16 #include <utility>
17 #include <vector>
18 
19 #include "base/base_paths.h"
20 #include "base/bind.h"
21 #include "base/bind_helpers.h"
22 #include "base/callback_helpers.h"
23 #include "base/command_line.h"
24 #include "base/environment.h"
25 #include "base/files/file.h"
26 #include "base/files/file_enumerator.h"
27 #include "base/files/file_path.h"
28 #include "base/files/scoped_file.h"
29 #include "base/files/scoped_temp_dir.h"
30 #include "base/guid.h"
31 #include "base/path_service.h"
32 #include "base/stl_util.h"
33 #include "base/strings/string_util.h"
34 #include "base/strings/stringprintf.h"
35 #include "base/strings/utf_string_conversions.h"
36 #include "base/test/multiprocess_test.h"
37 #include "base/test/scoped_environment_variable_override.h"
38 #include "base/test/test_file_util.h"
39 #include "base/test/test_timeouts.h"
40 #include "base/threading/platform_thread.h"
41 #include "base/threading/thread.h"
42 #include "base/time/time.h"
43 #include "build/build_config.h"
44 #include "testing/gtest/include/gtest/gtest.h"
45 #include "testing/multiprocess_func_list.h"
46 #include "testing/platform_test.h"
47 
48 #if defined(OS_WIN)
49 #include <shellapi.h>
50 #include <shlobj.h>
51 #include <tchar.h>
52 #include <windows.h>
53 #include <winioctl.h>
54 #include "base/strings/string_number_conversions.h"
55 #include "base/win/scoped_handle.h"
56 #include "base/win/win_util.h"
57 #endif
58 
59 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
60 #include <errno.h>
61 #include <fcntl.h>
62 #include <sys/ioctl.h>
63 #include <sys/types.h>
64 #include <unistd.h>
65 #endif
66 
67 #if defined(OS_LINUX)
68 #include <linux/fs.h>
69 #endif
70 
71 #if defined(OS_ANDROID)
72 #include "base/android/content_uri_utils.h"
73 #endif
74 
75 // This macro helps avoid wrapped lines in the test structs.
76 #define FPL(x) FILE_PATH_LITERAL(x)
77 
78 namespace base {
79 
80 namespace {
81 
82 const size_t kLargeFileSize = (1 << 16) + 3;
83 
84 // To test that NormalizeFilePath() deals with NTFS reparse points correctly,
85 // we need functions to create and delete reparse points.
86 #if defined(OS_WIN)
87 typedef struct _REPARSE_DATA_BUFFER {
88   ULONG  ReparseTag;
89   USHORT  ReparseDataLength;
90   USHORT  Reserved;
91   union {
92     struct {
93       USHORT SubstituteNameOffset;
94       USHORT SubstituteNameLength;
95       USHORT PrintNameOffset;
96       USHORT PrintNameLength;
97       ULONG Flags;
98       WCHAR PathBuffer[1];
99     } SymbolicLinkReparseBuffer;
100     struct {
101       USHORT SubstituteNameOffset;
102       USHORT SubstituteNameLength;
103       USHORT PrintNameOffset;
104       USHORT PrintNameLength;
105       WCHAR PathBuffer[1];
106     } MountPointReparseBuffer;
107     struct {
108       UCHAR DataBuffer[1];
109     } GenericReparseBuffer;
110   };
111 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
112 
113 // Sets a reparse point. |source| will now point to |target|. Returns true if
114 // the call succeeds, false otherwise.
SetReparsePoint(HANDLE source,const FilePath & target_path)115 bool SetReparsePoint(HANDLE source, const FilePath& target_path) {
116   std::wstring kPathPrefix = FILE_PATH_LITERAL("\\??\\");
117   std::wstring target_str;
118   // The juction will not work if the target path does not start with \??\ .
119   if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size()))
120     target_str += kPathPrefix;
121   target_str += target_path.value();
122   const wchar_t* target = target_str.c_str();
123   USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]);
124   char buffer[2000] = {0};
125   DWORD returned;
126 
127   REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
128 
129   data->ReparseTag = 0xa0000003;
130   memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2);
131 
132   data->MountPointReparseBuffer.SubstituteNameLength = size_target;
133   data->MountPointReparseBuffer.PrintNameOffset = size_target + 2;
134   data->ReparseDataLength = size_target + 4 + 8;
135 
136   int data_size = data->ReparseDataLength + 8;
137 
138   if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size,
139                        NULL, 0, &returned, NULL)) {
140     return false;
141   }
142   return true;
143 }
144 
145 // Delete the reparse point referenced by |source|. Returns true if the call
146 // succeeds, false otherwise.
DeleteReparsePoint(HANDLE source)147 bool DeleteReparsePoint(HANDLE source) {
148   DWORD returned;
149   REPARSE_DATA_BUFFER data = {0};
150   data.ReparseTag = 0xa0000003;
151   if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0,
152                        &returned, NULL)) {
153     return false;
154   }
155   return true;
156 }
157 
158 // Method that wraps the win32 GetShortPathName API. Returns an empty path on
159 // error.
MakeShortFilePath(const FilePath & input)160 FilePath MakeShortFilePath(const FilePath& input) {
161   DWORD path_short_len = ::GetShortPathName(input.value().c_str(), nullptr, 0);
162   if (path_short_len == 0UL)
163     return FilePath();
164 
165   std::wstring path_short_str;
166   path_short_len = ::GetShortPathName(
167       input.value().c_str(), WriteInto(&path_short_str, path_short_len),
168       path_short_len);
169   if (path_short_len == 0UL)
170     return FilePath();
171 
172   return FilePath(path_short_str);
173 }
174 
175 // Manages a reparse point for a test.
176 class ReparsePoint {
177  public:
178   // Creates a reparse point from |source| (an empty directory) to |target|.
ReparsePoint(const FilePath & source,const FilePath & target)179   ReparsePoint(const FilePath& source, const FilePath& target) {
180     dir_.Set(
181         ::CreateFile(source.value().c_str(), GENERIC_READ | GENERIC_WRITE,
182                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
183                      NULL, OPEN_EXISTING,
184                      FILE_FLAG_BACKUP_SEMANTICS,  // Needed to open a directory.
185                      NULL));
186     created_ = dir_.IsValid() && SetReparsePoint(dir_.Get(), target);
187   }
188 
~ReparsePoint()189   ~ReparsePoint() {
190     if (created_)
191       DeleteReparsePoint(dir_.Get());
192   }
193 
IsValid()194   bool IsValid() { return created_; }
195 
196  private:
197   win::ScopedHandle dir_;
198   bool created_;
199   DISALLOW_COPY_AND_ASSIGN(ReparsePoint);
200 };
201 
202 #endif
203 
204 // Fuchsia doesn't support file permissions.
205 #if !defined(OS_FUCHSIA)
206 #if defined(OS_POSIX)
207 // Provide a simple way to change the permissions bits on |path| in tests.
208 // ASSERT failures will return, but not stop the test.  Caller should wrap
209 // calls to this function in ASSERT_NO_FATAL_FAILURE().
ChangePosixFilePermissions(const FilePath & path,int mode_bits_to_set,int mode_bits_to_clear)210 void ChangePosixFilePermissions(const FilePath& path,
211                                 int mode_bits_to_set,
212                                 int mode_bits_to_clear) {
213   ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear)
214       << "Can't set and clear the same bits.";
215 
216   int mode = 0;
217   ASSERT_TRUE(GetPosixFilePermissions(path, &mode));
218   mode |= mode_bits_to_set;
219   mode &= ~mode_bits_to_clear;
220   ASSERT_TRUE(SetPosixFilePermissions(path, mode));
221 }
222 #endif  // defined(OS_POSIX)
223 
224 // Sets the source file to read-only.
SetReadOnly(const FilePath & path,bool read_only)225 void SetReadOnly(const FilePath& path, bool read_only) {
226 #if defined(OS_WIN)
227   // On Windows, it involves setting/removing the 'readonly' bit.
228   DWORD attrs = GetFileAttributes(path.value().c_str());
229   ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs);
230   ASSERT_TRUE(SetFileAttributes(
231       path.value().c_str(), read_only ? (attrs | FILE_ATTRIBUTE_READONLY)
232                                       : (attrs & ~FILE_ATTRIBUTE_READONLY)));
233 
234   DWORD expected =
235       read_only
236           ? ((attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY)) |
237              FILE_ATTRIBUTE_READONLY)
238           : (attrs & (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DIRECTORY));
239 
240   // Ignore FILE_ATTRIBUTE_NOT_CONTENT_INDEXED and FILE_ATTRIBUTE_COMPRESSED
241   // if present. These flags are set by the operating system, depending on
242   // local configurations, such as compressing the file system. Not filtering
243   // out these flags could cause tests to fail even though they should pass.
244   attrs = GetFileAttributes(path.value().c_str()) &
245           ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_COMPRESSED);
246   ASSERT_EQ(expected, attrs);
247 #else
248   // On all other platforms, it involves removing/setting the write bit.
249   mode_t mode = read_only ? S_IRUSR : (S_IRUSR | S_IWUSR);
250   EXPECT_TRUE(SetPosixFilePermissions(
251       path, DirectoryExists(path) ? (mode | S_IXUSR) : mode));
252 #endif  // defined(OS_WIN)
253 }
254 
IsReadOnly(const FilePath & path)255 bool IsReadOnly(const FilePath& path) {
256 #if defined(OS_WIN)
257   DWORD attrs = GetFileAttributes(path.value().c_str());
258   EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs);
259   return attrs & FILE_ATTRIBUTE_READONLY;
260 #else
261   int mode = 0;
262   EXPECT_TRUE(GetPosixFilePermissions(path, &mode));
263   return !(mode & S_IWUSR);
264 #endif  // defined(OS_WIN)
265 }
266 
267 #endif  // defined(OS_FUCHSIA)
268 
269 const wchar_t bogus_content[] = L"I'm cannon fodder.";
270 
271 const int FILES_AND_DIRECTORIES =
272     FileEnumerator::FILES | FileEnumerator::DIRECTORIES;
273 
274 // file_util winds up using autoreleased objects on the Mac, so this needs
275 // to be a PlatformTest
276 class FileUtilTest : public PlatformTest {
277  protected:
SetUp()278   void SetUp() override {
279     PlatformTest::SetUp();
280     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
281   }
282 
283   ScopedTempDir temp_dir_;
284 };
285 
286 // Collects all the results from the given file enumerator, and provides an
287 // interface to query whether a given file is present.
288 class FindResultCollector {
289  public:
FindResultCollector(FileEnumerator * enumerator)290   explicit FindResultCollector(FileEnumerator* enumerator) {
291     FilePath cur_file;
292     while (!(cur_file = enumerator->Next()).value().empty()) {
293       FilePath::StringType path = cur_file.value();
294       // The file should not be returned twice.
295       EXPECT_TRUE(files_.end() == files_.find(path))
296           << "Same file returned twice";
297 
298       // Save for later.
299       files_.insert(path);
300     }
301   }
302 
303   // Returns true if the enumerator found the file.
HasFile(const FilePath & file) const304   bool HasFile(const FilePath& file) const {
305     return files_.find(file.value()) != files_.end();
306   }
307 
size()308   int size() {
309     return static_cast<int>(files_.size());
310   }
311 
312  private:
313   std::set<FilePath::StringType> files_;
314 };
315 
316 // Simple function to dump some text into a new file.
CreateTextFile(const FilePath & filename,const std::wstring & contents)317 void CreateTextFile(const FilePath& filename,
318                     const std::wstring& contents) {
319   std::wofstream file;
320 #if defined(OS_WIN)
321   file.open(filename.value().c_str());
322 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
323   file.open(filename.value());
324 #endif  // OS_WIN
325   ASSERT_TRUE(file.is_open());
326   file << contents;
327   file.close();
328 }
329 
330 // Simple function to take out some text from a file.
ReadTextFile(const FilePath & filename)331 std::wstring ReadTextFile(const FilePath& filename) {
332   wchar_t contents[64];
333   std::wifstream file;
334 #if defined(OS_WIN)
335   file.open(filename.value().c_str());
336 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
337   file.open(filename.value());
338 #endif  // OS_WIN
339   EXPECT_TRUE(file.is_open());
340   file.getline(contents, size(contents));
341   file.close();
342   return std::wstring(contents);
343 }
344 
345 // Sets |is_inheritable| to indicate whether or not |stream| is set up to be
346 // inerhited into child processes (i.e., HANDLE_FLAG_INHERIT is set on the
347 // underlying handle on Windows, or FD_CLOEXEC is not set on the underlying file
348 // descriptor on POSIX). Calls to this function must be wrapped with
349 // ASSERT_NO_FATAL_FAILURE to properly abort tests in case of fatal failure.
GetIsInheritable(FILE * stream,bool * is_inheritable)350 void GetIsInheritable(FILE* stream, bool* is_inheritable) {
351 #if defined(OS_WIN)
352   HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(stream)));
353   ASSERT_NE(INVALID_HANDLE_VALUE, handle);
354 
355   DWORD info = 0;
356   ASSERT_EQ(TRUE, ::GetHandleInformation(handle, &info));
357   *is_inheritable = ((info & HANDLE_FLAG_INHERIT) != 0);
358 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
359   int fd = fileno(stream);
360   ASSERT_NE(-1, fd);
361   int flags = fcntl(fd, F_GETFD, 0);
362   ASSERT_NE(-1, flags);
363   *is_inheritable = ((flags & FD_CLOEXEC) == 0);
364 #else
365 #error Not implemented
366 #endif
367 }
368 
TEST_F(FileUtilTest,FileAndDirectorySize)369 TEST_F(FileUtilTest, FileAndDirectorySize) {
370   // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize
371   // should return 53 bytes.
372   FilePath file_01 = temp_dir_.GetPath().Append(FPL("The file 01.txt"));
373   CreateTextFile(file_01, L"12345678901234567890");
374   int64_t size_f1 = 0;
375   ASSERT_TRUE(GetFileSize(file_01, &size_f1));
376   EXPECT_EQ(20ll, size_f1);
377 
378   FilePath subdir_path = temp_dir_.GetPath().Append(FPL("Level2"));
379   CreateDirectory(subdir_path);
380 
381   FilePath file_02 = subdir_path.Append(FPL("The file 02.txt"));
382   CreateTextFile(file_02, L"123456789012345678901234567890");
383   int64_t size_f2 = 0;
384   ASSERT_TRUE(GetFileSize(file_02, &size_f2));
385   EXPECT_EQ(30ll, size_f2);
386 
387   FilePath subsubdir_path = subdir_path.Append(FPL("Level3"));
388   CreateDirectory(subsubdir_path);
389 
390   FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt"));
391   CreateTextFile(file_03, L"123");
392 
393   int64_t computed_size = ComputeDirectorySize(temp_dir_.GetPath());
394   EXPECT_EQ(size_f1 + size_f2 + 3, computed_size);
395 }
396 
TEST_F(FileUtilTest,NormalizeFilePathBasic)397 TEST_F(FileUtilTest, NormalizeFilePathBasic) {
398   // Create a directory under the test dir.  Because we create it,
399   // we know it is not a link.
400   FilePath file_a_path = temp_dir_.GetPath().Append(FPL("file_a"));
401   FilePath dir_path = temp_dir_.GetPath().Append(FPL("dir"));
402   FilePath file_b_path = dir_path.Append(FPL("file_b"));
403   CreateDirectory(dir_path);
404 
405   FilePath normalized_file_a_path, normalized_file_b_path;
406   ASSERT_FALSE(PathExists(file_a_path));
407   ASSERT_FALSE(NormalizeFilePath(file_a_path, &normalized_file_a_path))
408     << "NormalizeFilePath() should fail on nonexistent paths.";
409 
410   CreateTextFile(file_a_path, bogus_content);
411   ASSERT_TRUE(PathExists(file_a_path));
412   ASSERT_TRUE(NormalizeFilePath(file_a_path, &normalized_file_a_path));
413 
414   CreateTextFile(file_b_path, bogus_content);
415   ASSERT_TRUE(PathExists(file_b_path));
416   ASSERT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path));
417 
418   // Because this test created |dir_path|, we know it is not a link
419   // or junction.  So, the real path of the directory holding file a
420   // must be the parent of the path holding file b.
421   ASSERT_TRUE(normalized_file_a_path.DirName()
422       .IsParent(normalized_file_b_path.DirName()));
423 }
424 
425 #if defined(OS_WIN)
426 
TEST_F(FileUtilTest,NormalizeFileEmptyFile)427 TEST_F(FileUtilTest, NormalizeFileEmptyFile) {
428   // Create a directory under the test dir.  Because we create it,
429   // we know it is not a link.
430   const wchar_t empty_content[] = L"";
431 
432   FilePath file_a_path = temp_dir_.GetPath().Append(FPL("file_empty_a"));
433   FilePath dir_path = temp_dir_.GetPath().Append(FPL("dir"));
434   FilePath file_b_path = dir_path.Append(FPL("file_empty_b"));
435   ASSERT_TRUE(CreateDirectory(dir_path));
436 
437   FilePath normalized_file_a_path, normalized_file_b_path;
438   ASSERT_FALSE(PathExists(file_a_path));
439   EXPECT_FALSE(NormalizeFilePath(file_a_path, &normalized_file_a_path))
440       << "NormalizeFilePath() should fail on nonexistent paths.";
441 
442   CreateTextFile(file_a_path, empty_content);
443   ASSERT_TRUE(PathExists(file_a_path));
444   EXPECT_TRUE(NormalizeFilePath(file_a_path, &normalized_file_a_path));
445 
446   CreateTextFile(file_b_path, empty_content);
447   ASSERT_TRUE(PathExists(file_b_path));
448   EXPECT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path));
449 
450   // Because this test created |dir_path|, we know it is not a link
451   // or junction.  So, the real path of the directory holding file a
452   // must be the parent of the path holding file b.
453   EXPECT_TRUE(normalized_file_a_path.DirName().IsParent(
454       normalized_file_b_path.DirName()));
455 }
456 
TEST_F(FileUtilTest,NormalizeFilePathReparsePoints)457 TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) {
458   // Build the following directory structure:
459   //
460   // temp_dir
461   // |-> base_a
462   // |   |-> sub_a
463   // |       |-> file.txt
464   // |       |-> long_name___... (Very long name.)
465   // |           |-> sub_long
466   // |              |-> deep.txt
467   // |-> base_b
468   //     |-> to_sub_a (reparse point to temp_dir\base_a\sub_a)
469   //     |-> to_base_b (reparse point to temp_dir\base_b)
470   //     |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long)
471 
472   FilePath base_a = temp_dir_.GetPath().Append(FPL("base_a"));
473 #if defined(OS_WIN)
474   // TEMP can have a lower case drive letter.
475   std::wstring temp_base_a = base_a.value();
476   ASSERT_FALSE(temp_base_a.empty());
477   temp_base_a[0] = ToUpperASCII(char16{temp_base_a[0]});
478   base_a = FilePath(temp_base_a);
479 #endif
480   ASSERT_TRUE(CreateDirectory(base_a));
481 #if defined(OS_WIN)
482   // TEMP might be a short name which is not normalized.
483   base_a = MakeLongFilePath(base_a);
484 #endif
485 
486   FilePath sub_a = base_a.Append(FPL("sub_a"));
487   ASSERT_TRUE(CreateDirectory(sub_a));
488 
489   FilePath file_txt = sub_a.Append(FPL("file.txt"));
490   CreateTextFile(file_txt, bogus_content);
491 
492   // Want a directory whose name is long enough to make the path to the file
493   // inside just under MAX_PATH chars.  This will be used to test that when
494   // a junction expands to a path over MAX_PATH chars in length,
495   // NormalizeFilePath() fails without crashing.
496   FilePath sub_long_rel(FPL("sub_long"));
497   FilePath deep_txt(FPL("deep.txt"));
498 
499   int target_length = MAX_PATH;
500   target_length -= (sub_a.value().length() + 1);  // +1 for the sepperator '\'.
501   target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1);
502   // Without making the path a bit shorter, CreateDirectory() fails.
503   // the resulting path is still long enough to hit the failing case in
504   // NormalizePath().
505   const int kCreateDirLimit = 4;
506   target_length -= kCreateDirLimit;
507   FilePath::StringType long_name_str = FPL("long_name_");
508   long_name_str.resize(target_length, '_');
509 
510   FilePath long_name = sub_a.Append(FilePath(long_name_str));
511   FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt);
512   ASSERT_EQ(static_cast<size_t>(MAX_PATH - kCreateDirLimit),
513             deep_file.value().length());
514 
515   FilePath sub_long = deep_file.DirName();
516   ASSERT_TRUE(CreateDirectory(sub_long));
517   CreateTextFile(deep_file, bogus_content);
518 
519   FilePath base_b = temp_dir_.GetPath().Append(FPL("base_b"));
520   ASSERT_TRUE(CreateDirectory(base_b));
521 #if defined(OS_WIN)
522   // TEMP might be a short name which is not normalized.
523   base_b = MakeLongFilePath(base_b);
524 #endif
525 
526   FilePath to_sub_a = base_b.Append(FPL("to_sub_a"));
527   ASSERT_TRUE(CreateDirectory(to_sub_a));
528   FilePath normalized_path;
529   {
530     ReparsePoint reparse_to_sub_a(to_sub_a, sub_a);
531     ASSERT_TRUE(reparse_to_sub_a.IsValid());
532 
533     FilePath to_base_b = base_b.Append(FPL("to_base_b"));
534     ASSERT_TRUE(CreateDirectory(to_base_b));
535     ReparsePoint reparse_to_base_b(to_base_b, base_b);
536     ASSERT_TRUE(reparse_to_base_b.IsValid());
537 
538     FilePath to_sub_long = base_b.Append(FPL("to_sub_long"));
539     ASSERT_TRUE(CreateDirectory(to_sub_long));
540     ReparsePoint reparse_to_sub_long(to_sub_long, sub_long);
541     ASSERT_TRUE(reparse_to_sub_long.IsValid());
542 
543     // Normalize a junction free path: base_a\sub_a\file.txt .
544     ASSERT_TRUE(NormalizeFilePath(file_txt, &normalized_path));
545     ASSERT_EQ(file_txt.value(), normalized_path.value());
546 
547     // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude
548     // the junction to_sub_a.
549     ASSERT_TRUE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
550                                              &normalized_path));
551     ASSERT_EQ(file_txt.value(), normalized_path.value());
552 
553     // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be
554     // normalized to exclude junctions to_base_b and to_sub_a .
555     ASSERT_TRUE(NormalizeFilePath(base_b.Append(FPL("to_base_b"))
556                                                    .Append(FPL("to_base_b"))
557                                                    .Append(FPL("to_sub_a"))
558                                                    .Append(FPL("file.txt")),
559                                              &normalized_path));
560     ASSERT_EQ(file_txt.value(), normalized_path.value());
561 
562     // A long enough path will cause NormalizeFilePath() to fail.  Make a long
563     // path using to_base_b many times, and check that paths long enough to fail
564     // do not cause a crash.
565     FilePath long_path = base_b;
566     const int kLengthLimit = MAX_PATH + 200;
567     while (long_path.value().length() <= kLengthLimit) {
568       long_path = long_path.Append(FPL("to_base_b"));
569     }
570     long_path = long_path.Append(FPL("to_sub_a"))
571                          .Append(FPL("file.txt"));
572 
573     ASSERT_FALSE(NormalizeFilePath(long_path, &normalized_path));
574 
575     // Normalizing the junction to deep.txt should fail, because the expanded
576     // path to deep.txt is longer than MAX_PATH.
577     ASSERT_FALSE(NormalizeFilePath(to_sub_long.Append(deep_txt),
578                                               &normalized_path));
579 
580     // Delete the reparse points, and see that NormalizeFilePath() fails
581     // to traverse them.
582   }
583 
584   ASSERT_FALSE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
585                                             &normalized_path));
586 }
587 
TEST_F(FileUtilTest,DevicePathToDriveLetter)588 TEST_F(FileUtilTest, DevicePathToDriveLetter) {
589   // Get a drive letter.
590   std::wstring real_drive_letter = AsWString(
591       ToUpperASCII(AsStringPiece16(temp_dir_.GetPath().value().substr(0, 2))));
592   if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) {
593     LOG(ERROR) << "Can't get a drive letter to test with.";
594     return;
595   }
596 
597   // Get the NT style path to that drive.
598   wchar_t device_path[MAX_PATH] = {'\0'};
599   ASSERT_TRUE(
600       ::QueryDosDevice(real_drive_letter.c_str(), device_path, MAX_PATH));
601   FilePath actual_device_path(device_path);
602   FilePath win32_path;
603 
604   // Run DevicePathToDriveLetterPath() on the NT style path we got from
605   // QueryDosDevice().  Expect the drive letter we started with.
606   ASSERT_TRUE(DevicePathToDriveLetterPath(actual_device_path, &win32_path));
607   ASSERT_EQ(real_drive_letter, win32_path.value());
608 
609   // Add some directories to the path.  Expect those extra path componenets
610   // to be preserved.
611   FilePath kRelativePath(FPL("dir1\\dir2\\file.txt"));
612   ASSERT_TRUE(DevicePathToDriveLetterPath(
613       actual_device_path.Append(kRelativePath),
614       &win32_path));
615   EXPECT_EQ(FilePath(real_drive_letter + FILE_PATH_LITERAL("\\"))
616                 .Append(kRelativePath)
617                 .value(),
618             win32_path.value());
619 
620   // Deform the real path so that it is invalid by removing the last four
621   // characters.  The way windows names devices that are hard disks
622   // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer
623   // than three characters.  The only way the truncated string could be a
624   // real drive is if more than 10^3 disks are mounted:
625   // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1
626   // Check that DevicePathToDriveLetterPath fails.
627   size_t path_length = actual_device_path.value().length();
628   size_t new_length = path_length - 4;
629   ASSERT_GT(new_length, 0u);
630   FilePath prefix_of_real_device_path(
631       actual_device_path.value().substr(0, new_length));
632   ASSERT_FALSE(DevicePathToDriveLetterPath(prefix_of_real_device_path,
633                                            &win32_path));
634 
635   ASSERT_FALSE(DevicePathToDriveLetterPath(
636       prefix_of_real_device_path.Append(kRelativePath),
637       &win32_path));
638 
639   // Deform the real path so that it is invalid by adding some characters. For
640   // example, if C: maps to \Device\HardDiskVolume8, then we simulate a
641   // request for the drive letter whose native path is
642   // \Device\HardDiskVolume812345 .  We assume such a device does not exist,
643   // because drives are numbered in order and mounting 112345 hard disks will
644   // never happen.
645   const FilePath::StringType kExtraChars = FPL("12345");
646 
647   FilePath real_device_path_plus_numbers(
648       actual_device_path.value() + kExtraChars);
649 
650   ASSERT_FALSE(DevicePathToDriveLetterPath(
651       real_device_path_plus_numbers,
652       &win32_path));
653 
654   ASSERT_FALSE(DevicePathToDriveLetterPath(
655       real_device_path_plus_numbers.Append(kRelativePath),
656       &win32_path));
657 }
658 
TEST_F(FileUtilTest,CreateTemporaryFileInDirLongPathTest)659 TEST_F(FileUtilTest, CreateTemporaryFileInDirLongPathTest) {
660   // Test that CreateTemporaryFileInDir() creates a path and returns a long path
661   // if it is available. This test requires that:
662   // - the filesystem at |temp_dir_| supports long filenames.
663   // - the account has FILE_LIST_DIRECTORY permission for all ancestor
664   //   directories of |temp_dir_|.
665   constexpr FilePath::CharType kLongDirName[] = FPL("A long path");
666   constexpr FilePath::CharType kTestSubDirName[] = FPL("test");
667   FilePath long_test_dir = temp_dir_.GetPath().Append(kLongDirName);
668   ASSERT_TRUE(CreateDirectory(long_test_dir));
669 
670   // kLongDirName is not a 8.3 component. So ::GetShortPathName() should give us
671   // a different short name.
672   FilePath short_test_dir = MakeShortFilePath(long_test_dir);
673   ASSERT_FALSE(short_test_dir.empty());
674   ASSERT_NE(kLongDirName, short_test_dir.BaseName().value());
675 
676   FilePath temp_file;
677   ASSERT_TRUE(CreateTemporaryFileInDir(short_test_dir, &temp_file));
678   EXPECT_EQ(kLongDirName, temp_file.DirName().BaseName().value());
679   EXPECT_TRUE(PathExists(temp_file));
680 
681   // Create a subdirectory of |long_test_dir| and make |long_test_dir|
682   // unreadable. We should still be able to create a temp file in the
683   // subdirectory, but we won't be able to determine the long path for it. This
684   // mimics the environment that some users run where their user profiles reside
685   // in a location where the don't have full access to the higher level
686   // directories. (Note that this assumption is true for NTFS, but not for some
687   // network file systems. E.g. AFS).
688   FilePath access_test_dir = long_test_dir.Append(kTestSubDirName);
689   ASSERT_TRUE(CreateDirectory(access_test_dir));
690   FilePermissionRestorer long_test_dir_restorer(long_test_dir);
691   ASSERT_TRUE(MakeFileUnreadable(long_test_dir));
692 
693   // Use the short form of the directory to create a temporary filename.
694   ASSERT_TRUE(CreateTemporaryFileInDir(
695       short_test_dir.Append(kTestSubDirName), &temp_file));
696   EXPECT_TRUE(PathExists(temp_file));
697   EXPECT_TRUE(short_test_dir.IsParent(temp_file.DirName()));
698 
699   // Check that the long path can't be determined for |temp_file|.
700   // Helper method base::MakeLongFilePath returns an empty path on error.
701   FilePath temp_file_long = MakeLongFilePath(temp_file);
702   ASSERT_TRUE(temp_file_long.empty());
703 }
704 
TEST_F(FileUtilTest,MakeLongFilePathTest)705 TEST_F(FileUtilTest, MakeLongFilePathTest) {
706   // Tests helper function base::MakeLongFilePath
707 
708   // If a username isn't a valid 8.3 short file name (even just a
709   // lengthy name like "user with long name"), Windows will set the TMP and TEMP
710   // environment variables to be 8.3 paths. ::GetTempPath (called in
711   // base::GetTempDir) just uses the value specified by TMP or TEMP, and so can
712   // return a short path. So from the start need to use MakeLongFilePath
713   // to normalize the path for such test environments.
714   FilePath temp_dir_long = MakeLongFilePath(temp_dir_.GetPath());
715   ASSERT_FALSE(temp_dir_long.empty());
716 
717   FilePath long_test_dir = temp_dir_long.Append(FPL("A long directory name"));
718   ASSERT_TRUE(CreateDirectory(long_test_dir));
719 
720   // Directory name is not a 8.3 component. So ::GetShortPathName() should give
721   // us a different short name.
722   FilePath short_test_dir = MakeShortFilePath(long_test_dir);
723   ASSERT_FALSE(short_test_dir.empty());
724 
725   EXPECT_NE(long_test_dir, short_test_dir);
726   EXPECT_EQ(long_test_dir, MakeLongFilePath(short_test_dir));
727 
728   FilePath long_test_file = long_test_dir.Append(FPL("A long file name.1234"));
729   CreateTextFile(long_test_file, bogus_content);
730   ASSERT_TRUE(PathExists(long_test_file));
731 
732   // File name is not a 8.3 component. So ::GetShortPathName() should give us
733   // a different short name.
734   FilePath short_test_file = MakeShortFilePath(long_test_file);
735   ASSERT_FALSE(short_test_file.empty());
736 
737   EXPECT_NE(long_test_file, short_test_file);
738   EXPECT_EQ(long_test_file, MakeLongFilePath(short_test_file));
739 
740   // MakeLongFilePath should return empty path if file does not exist.
741   EXPECT_TRUE(DeleteFile(short_test_file, false));
742   EXPECT_TRUE(MakeLongFilePath(short_test_file).empty());
743 
744   // MakeLongFilePath should return empty path if directory does not exist.
745   EXPECT_TRUE(DeleteFile(short_test_dir, false));
746   EXPECT_TRUE(MakeLongFilePath(short_test_dir).empty());
747 }
748 
TEST_F(FileUtilTest,CreateWinHardlinkTest)749 TEST_F(FileUtilTest, CreateWinHardlinkTest) {
750   // Link to a different file name in a sub-directory of |temp_dir_|.
751   FilePath test_dir = temp_dir_.GetPath().Append(FPL("test"));
752   ASSERT_TRUE(CreateDirectory(test_dir));
753   FilePath temp_file;
754   ASSERT_TRUE(CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file));
755   FilePath link_to_file = test_dir.Append(FPL("linked_name"));
756   EXPECT_TRUE(CreateWinHardLink(link_to_file, temp_file));
757   EXPECT_TRUE(PathExists(link_to_file));
758 
759   // Link two directories. This should fail. Verify that failure is returned
760   // by CreateWinHardLink.
761   EXPECT_FALSE(CreateWinHardLink(temp_dir_.GetPath(), test_dir));
762 }
763 
764 #endif  // defined(OS_WIN)
765 
766 #if defined(OS_POSIX)
767 
TEST_F(FileUtilTest,CreateAndReadSymlinks)768 TEST_F(FileUtilTest, CreateAndReadSymlinks) {
769   FilePath link_from = temp_dir_.GetPath().Append(FPL("from_file"));
770   FilePath link_to = temp_dir_.GetPath().Append(FPL("to_file"));
771   CreateTextFile(link_to, bogus_content);
772 
773   ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
774     << "Failed to create file symlink.";
775 
776   // If we created the link properly, we should be able to read the contents
777   // through it.
778   EXPECT_EQ(bogus_content, ReadTextFile(link_from));
779 
780   FilePath result;
781   ASSERT_TRUE(ReadSymbolicLink(link_from, &result));
782   EXPECT_EQ(link_to.value(), result.value());
783 
784   // Link to a directory.
785   link_from = temp_dir_.GetPath().Append(FPL("from_dir"));
786   link_to = temp_dir_.GetPath().Append(FPL("to_dir"));
787   ASSERT_TRUE(CreateDirectory(link_to));
788   ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
789     << "Failed to create directory symlink.";
790 
791   // Test failures.
792   EXPECT_FALSE(CreateSymbolicLink(link_to, link_to));
793   EXPECT_FALSE(ReadSymbolicLink(link_to, &result));
794   FilePath missing = temp_dir_.GetPath().Append(FPL("missing"));
795   EXPECT_FALSE(ReadSymbolicLink(missing, &result));
796 }
797 
798 // The following test of NormalizeFilePath() require that we create a symlink.
799 // This can not be done on Windows before Vista.  On Vista, creating a symlink
800 // requires privilege "SeCreateSymbolicLinkPrivilege".
801 // TODO(skerner): Investigate the possibility of giving base_unittests the
802 // privileges required to create a symlink.
TEST_F(FileUtilTest,NormalizeFilePathSymlinks)803 TEST_F(FileUtilTest, NormalizeFilePathSymlinks) {
804   // Link one file to another.
805   FilePath link_from = temp_dir_.GetPath().Append(FPL("from_file"));
806   FilePath link_to = temp_dir_.GetPath().Append(FPL("to_file"));
807   CreateTextFile(link_to, bogus_content);
808 
809   ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
810     << "Failed to create file symlink.";
811 
812   // Check that NormalizeFilePath sees the link.
813   FilePath normalized_path;
814   ASSERT_TRUE(NormalizeFilePath(link_from, &normalized_path));
815   EXPECT_NE(link_from, link_to);
816   EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value());
817   EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value());
818 
819   // Link to a directory.
820   link_from = temp_dir_.GetPath().Append(FPL("from_dir"));
821   link_to = temp_dir_.GetPath().Append(FPL("to_dir"));
822   ASSERT_TRUE(CreateDirectory(link_to));
823   ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
824     << "Failed to create directory symlink.";
825 
826   EXPECT_FALSE(NormalizeFilePath(link_from, &normalized_path))
827     << "Links to directories should return false.";
828 
829   // Test that a loop in the links causes NormalizeFilePath() to return false.
830   link_from = temp_dir_.GetPath().Append(FPL("link_a"));
831   link_to = temp_dir_.GetPath().Append(FPL("link_b"));
832   ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
833     << "Failed to create loop symlink a.";
834   ASSERT_TRUE(CreateSymbolicLink(link_from, link_to))
835     << "Failed to create loop symlink b.";
836 
837   // Infinite loop!
838   EXPECT_FALSE(NormalizeFilePath(link_from, &normalized_path));
839 }
840 
TEST_F(FileUtilTest,DeleteSymlinkToExistentFile)841 TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) {
842   // Create a file.
843   FilePath file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt"));
844   CreateTextFile(file_name, bogus_content);
845   ASSERT_TRUE(PathExists(file_name));
846 
847   // Create a symlink to the file.
848   FilePath file_link = temp_dir_.GetPath().Append("file_link_2");
849   ASSERT_TRUE(CreateSymbolicLink(file_name, file_link))
850       << "Failed to create symlink.";
851 
852   // Delete the symbolic link.
853   EXPECT_TRUE(DeleteFile(file_link, false));
854 
855   // Make sure original file is not deleted.
856   EXPECT_FALSE(PathExists(file_link));
857   EXPECT_TRUE(PathExists(file_name));
858 }
859 
TEST_F(FileUtilTest,DeleteSymlinkToNonExistentFile)860 TEST_F(FileUtilTest, DeleteSymlinkToNonExistentFile) {
861   // Create a non-existent file path.
862   FilePath non_existent =
863       temp_dir_.GetPath().Append(FPL("Test DeleteFile 3.txt"));
864   EXPECT_FALSE(PathExists(non_existent));
865 
866   // Create a symlink to the non-existent file.
867   FilePath file_link = temp_dir_.GetPath().Append("file_link_3");
868   ASSERT_TRUE(CreateSymbolicLink(non_existent, file_link))
869       << "Failed to create symlink.";
870 
871   // Make sure the symbolic link is exist.
872   EXPECT_TRUE(IsLink(file_link));
873   EXPECT_FALSE(PathExists(file_link));
874 
875   // Delete the symbolic link.
876   EXPECT_TRUE(DeleteFile(file_link, false));
877 
878   // Make sure the symbolic link is deleted.
879   EXPECT_FALSE(IsLink(file_link));
880 }
881 
TEST_F(FileUtilTest,CopyFileFollowsSymlinks)882 TEST_F(FileUtilTest, CopyFileFollowsSymlinks) {
883   FilePath link_from = temp_dir_.GetPath().Append(FPL("from_file"));
884   FilePath link_to = temp_dir_.GetPath().Append(FPL("to_file"));
885   CreateTextFile(link_to, bogus_content);
886 
887   ASSERT_TRUE(CreateSymbolicLink(link_to, link_from));
888 
889   // If we created the link properly, we should be able to read the contents
890   // through it.
891   EXPECT_EQ(bogus_content, ReadTextFile(link_from));
892 
893   FilePath result;
894   ASSERT_TRUE(ReadSymbolicLink(link_from, &result));
895   EXPECT_EQ(link_to.value(), result.value());
896 
897   // Create another file and copy it to |link_from|.
898   FilePath src_file = temp_dir_.GetPath().Append(FPL("src.txt"));
899   const std::wstring file_contents(L"Gooooooooooooooooooooogle");
900   CreateTextFile(src_file, file_contents);
901   ASSERT_TRUE(CopyFile(src_file, link_from));
902 
903   // Make sure |link_from| is still a symlink, and |link_to| has been written to
904   // by CopyFile().
905   EXPECT_TRUE(IsLink(link_from));
906   EXPECT_EQ(file_contents, ReadTextFile(link_from));
907   EXPECT_EQ(file_contents, ReadTextFile(link_to));
908 }
909 
TEST_F(FileUtilTest,ChangeFilePermissionsAndRead)910 TEST_F(FileUtilTest, ChangeFilePermissionsAndRead) {
911   // Create a file path.
912   FilePath file_name =
913       temp_dir_.GetPath().Append(FPL("Test Readable File.txt"));
914   EXPECT_FALSE(PathExists(file_name));
915 
916   static constexpr char kData[] = "hello";
917   static constexpr int kDataSize = sizeof(kData) - 1;
918   char buffer[kDataSize];
919 
920   // Write file.
921   EXPECT_EQ(kDataSize, WriteFile(file_name, kData, kDataSize));
922   EXPECT_TRUE(PathExists(file_name));
923 
924   // Make sure the file is readable.
925   int32_t mode = 0;
926   EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
927   EXPECT_TRUE(mode & FILE_PERMISSION_READ_BY_USER);
928 
929   // Get rid of the read permission.
930   EXPECT_TRUE(SetPosixFilePermissions(file_name, 0u));
931   EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
932   EXPECT_FALSE(mode & FILE_PERMISSION_READ_BY_USER);
933   // Make sure the file can't be read.
934   EXPECT_EQ(-1, ReadFile(file_name, buffer, kDataSize));
935 
936   // Give the read permission.
937   EXPECT_TRUE(SetPosixFilePermissions(file_name, FILE_PERMISSION_READ_BY_USER));
938   EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
939   EXPECT_TRUE(mode & FILE_PERMISSION_READ_BY_USER);
940   // Make sure the file can be read.
941   EXPECT_EQ(kDataSize, ReadFile(file_name, buffer, kDataSize));
942 
943   // Delete the file.
944   EXPECT_TRUE(DeleteFile(file_name, false));
945   EXPECT_FALSE(PathExists(file_name));
946 }
947 
TEST_F(FileUtilTest,ChangeFilePermissionsAndWrite)948 TEST_F(FileUtilTest, ChangeFilePermissionsAndWrite) {
949   // Create a file path.
950   FilePath file_name =
951       temp_dir_.GetPath().Append(FPL("Test Readable File.txt"));
952   EXPECT_FALSE(PathExists(file_name));
953 
954   const std::string kData("hello");
955 
956   // Write file.
957   EXPECT_EQ(static_cast<int>(kData.length()),
958             WriteFile(file_name, kData.data(), kData.length()));
959   EXPECT_TRUE(PathExists(file_name));
960 
961   // Make sure the file is writable.
962   int mode = 0;
963   EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
964   EXPECT_TRUE(mode & FILE_PERMISSION_WRITE_BY_USER);
965   EXPECT_TRUE(PathIsWritable(file_name));
966 
967   // Get rid of the write permission.
968   EXPECT_TRUE(SetPosixFilePermissions(file_name, 0u));
969   EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
970   EXPECT_FALSE(mode & FILE_PERMISSION_WRITE_BY_USER);
971   // Make sure the file can't be write.
972   EXPECT_EQ(-1, WriteFile(file_name, kData.data(), kData.length()));
973   EXPECT_FALSE(PathIsWritable(file_name));
974 
975   // Give read permission.
976   EXPECT_TRUE(SetPosixFilePermissions(file_name,
977                                       FILE_PERMISSION_WRITE_BY_USER));
978   EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
979   EXPECT_TRUE(mode & FILE_PERMISSION_WRITE_BY_USER);
980   // Make sure the file can be write.
981   EXPECT_EQ(static_cast<int>(kData.length()),
982             WriteFile(file_name, kData.data(), kData.length()));
983   EXPECT_TRUE(PathIsWritable(file_name));
984 
985   // Delete the file.
986   EXPECT_TRUE(DeleteFile(file_name, false));
987   EXPECT_FALSE(PathExists(file_name));
988 }
989 
TEST_F(FileUtilTest,ChangeDirectoryPermissionsAndEnumerate)990 TEST_F(FileUtilTest, ChangeDirectoryPermissionsAndEnumerate) {
991   // Create a directory path.
992   FilePath subdir_path = temp_dir_.GetPath().Append(FPL("PermissionTest1"));
993   CreateDirectory(subdir_path);
994   ASSERT_TRUE(PathExists(subdir_path));
995 
996   // Create a dummy file to enumerate.
997   FilePath file_name = subdir_path.Append(FPL("Test Readable File.txt"));
998   EXPECT_FALSE(PathExists(file_name));
999   const std::string kData("hello");
1000   EXPECT_EQ(static_cast<int>(kData.length()),
1001             WriteFile(file_name, kData.data(), kData.length()));
1002   EXPECT_TRUE(PathExists(file_name));
1003 
1004   // Make sure the directory has the all permissions.
1005   int mode = 0;
1006   EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
1007   EXPECT_EQ(FILE_PERMISSION_USER_MASK, mode & FILE_PERMISSION_USER_MASK);
1008 
1009   // Get rid of the permissions from the directory.
1010   EXPECT_TRUE(SetPosixFilePermissions(subdir_path, 0u));
1011   EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
1012   EXPECT_FALSE(mode & FILE_PERMISSION_USER_MASK);
1013 
1014   // Make sure the file in the directory can't be enumerated.
1015   FileEnumerator f1(subdir_path, true, FileEnumerator::FILES);
1016   EXPECT_TRUE(PathExists(subdir_path));
1017   FindResultCollector c1(&f1);
1018   EXPECT_EQ(0, c1.size());
1019   EXPECT_FALSE(GetPosixFilePermissions(file_name, &mode));
1020 
1021   // Give the permissions to the directory.
1022   EXPECT_TRUE(SetPosixFilePermissions(subdir_path, FILE_PERMISSION_USER_MASK));
1023   EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
1024   EXPECT_EQ(FILE_PERMISSION_USER_MASK, mode & FILE_PERMISSION_USER_MASK);
1025 
1026   // Make sure the file in the directory can be enumerated.
1027   FileEnumerator f2(subdir_path, true, FileEnumerator::FILES);
1028   FindResultCollector c2(&f2);
1029   EXPECT_TRUE(c2.HasFile(file_name));
1030   EXPECT_EQ(1, c2.size());
1031 
1032   // Delete the file.
1033   EXPECT_TRUE(DeleteFileRecursively(subdir_path));
1034   EXPECT_FALSE(PathExists(subdir_path));
1035 }
1036 
TEST_F(FileUtilTest,ExecutableExistsInPath)1037 TEST_F(FileUtilTest, ExecutableExistsInPath) {
1038   // Create two directories that we will put in our PATH
1039   const FilePath::CharType kDir1[] = FPL("dir1");
1040   const FilePath::CharType kDir2[] = FPL("dir2");
1041 
1042   FilePath dir1 = temp_dir_.GetPath().Append(kDir1);
1043   FilePath dir2 = temp_dir_.GetPath().Append(kDir2);
1044   ASSERT_TRUE(CreateDirectory(dir1));
1045   ASSERT_TRUE(CreateDirectory(dir2));
1046 
1047   test::ScopedEnvironmentVariableOverride scoped_env(
1048       "PATH", dir1.value() + ":" + dir2.value());
1049   ASSERT_TRUE(scoped_env.IsOverridden());
1050 
1051   const FilePath::CharType kRegularFileName[] = FPL("regular_file");
1052   const FilePath::CharType kExeFileName[] = FPL("exe");
1053   const FilePath::CharType kDneFileName[] = FPL("does_not_exist");
1054 
1055   const FilePath kExePath = dir1.Append(kExeFileName);
1056   const FilePath kRegularFilePath = dir2.Append(kRegularFileName);
1057 
1058   // Write file.
1059   const std::string kData("hello");
1060   ASSERT_EQ(static_cast<int>(kData.length()),
1061             WriteFile(kExePath, kData.data(), kData.length()));
1062   ASSERT_TRUE(PathExists(kExePath));
1063   ASSERT_EQ(static_cast<int>(kData.length()),
1064             WriteFile(kRegularFilePath, kData.data(), kData.length()));
1065   ASSERT_TRUE(PathExists(kRegularFilePath));
1066 
1067   ASSERT_TRUE(SetPosixFilePermissions(dir1.Append(kExeFileName),
1068                                       FILE_PERMISSION_EXECUTE_BY_USER));
1069 
1070   EXPECT_TRUE(ExecutableExistsInPath(scoped_env.GetEnv(), kExeFileName));
1071   EXPECT_FALSE(ExecutableExistsInPath(scoped_env.GetEnv(), kRegularFileName));
1072   EXPECT_FALSE(ExecutableExistsInPath(scoped_env.GetEnv(), kDneFileName));
1073 }
1074 
TEST_F(FileUtilTest,CopyDirectoryPermissions)1075 TEST_F(FileUtilTest, CopyDirectoryPermissions) {
1076   // Create a directory.
1077   FilePath dir_name_from =
1078       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1079   CreateDirectory(dir_name_from);
1080   ASSERT_TRUE(PathExists(dir_name_from));
1081 
1082   // Create some regular files under the directory with various permissions.
1083   FilePath file_name_from =
1084       dir_name_from.Append(FILE_PATH_LITERAL("Reggy-1.txt"));
1085   CreateTextFile(file_name_from, L"Mordecai");
1086   ASSERT_TRUE(PathExists(file_name_from));
1087   ASSERT_TRUE(SetPosixFilePermissions(file_name_from, 0755));
1088 
1089   FilePath file2_name_from =
1090       dir_name_from.Append(FILE_PATH_LITERAL("Reggy-2.txt"));
1091   CreateTextFile(file2_name_from, L"Rigby");
1092   ASSERT_TRUE(PathExists(file2_name_from));
1093   ASSERT_TRUE(SetPosixFilePermissions(file2_name_from, 0777));
1094 
1095   FilePath file3_name_from =
1096       dir_name_from.Append(FILE_PATH_LITERAL("Reggy-3.txt"));
1097   CreateTextFile(file3_name_from, L"Benson");
1098   ASSERT_TRUE(PathExists(file3_name_from));
1099   ASSERT_TRUE(SetPosixFilePermissions(file3_name_from, 0400));
1100 
1101   // Copy the directory recursively.
1102   FilePath dir_name_to =
1103       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1104   FilePath file_name_to =
1105       dir_name_to.Append(FILE_PATH_LITERAL("Reggy-1.txt"));
1106   FilePath file2_name_to =
1107       dir_name_to.Append(FILE_PATH_LITERAL("Reggy-2.txt"));
1108   FilePath file3_name_to =
1109       dir_name_to.Append(FILE_PATH_LITERAL("Reggy-3.txt"));
1110 
1111   ASSERT_FALSE(PathExists(dir_name_to));
1112 
1113   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, true));
1114   ASSERT_TRUE(PathExists(file_name_to));
1115   ASSERT_TRUE(PathExists(file2_name_to));
1116   ASSERT_TRUE(PathExists(file3_name_to));
1117 
1118   int mode = 0;
1119   int expected_mode;
1120   ASSERT_TRUE(GetPosixFilePermissions(file_name_to, &mode));
1121 #if defined(OS_MACOSX)
1122   expected_mode = 0755;
1123 #elif defined(OS_CHROMEOS)
1124   expected_mode = 0644;
1125 #else
1126   expected_mode = 0600;
1127 #endif
1128   EXPECT_EQ(expected_mode, mode);
1129 
1130   ASSERT_TRUE(GetPosixFilePermissions(file2_name_to, &mode));
1131 #if defined(OS_MACOSX)
1132   expected_mode = 0755;
1133 #elif defined(OS_CHROMEOS)
1134   expected_mode = 0644;
1135 #else
1136   expected_mode = 0600;
1137 #endif
1138   EXPECT_EQ(expected_mode, mode);
1139 
1140   ASSERT_TRUE(GetPosixFilePermissions(file3_name_to, &mode));
1141 #if defined(OS_MACOSX)
1142   expected_mode = 0600;
1143 #elif defined(OS_CHROMEOS)
1144   expected_mode = 0644;
1145 #else
1146   expected_mode = 0600;
1147 #endif
1148   EXPECT_EQ(expected_mode, mode);
1149 }
1150 
TEST_F(FileUtilTest,CopyDirectoryPermissionsOverExistingFile)1151 TEST_F(FileUtilTest, CopyDirectoryPermissionsOverExistingFile) {
1152   // Create a directory.
1153   FilePath dir_name_from =
1154       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1155   CreateDirectory(dir_name_from);
1156   ASSERT_TRUE(PathExists(dir_name_from));
1157 
1158   // Create a file under the directory.
1159   FilePath file_name_from =
1160       dir_name_from.Append(FILE_PATH_LITERAL("Reggy-1.txt"));
1161   CreateTextFile(file_name_from, L"Mordecai");
1162   ASSERT_TRUE(PathExists(file_name_from));
1163   ASSERT_TRUE(SetPosixFilePermissions(file_name_from, 0644));
1164 
1165   // Create a directory.
1166   FilePath dir_name_to =
1167       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1168   CreateDirectory(dir_name_to);
1169   ASSERT_TRUE(PathExists(dir_name_to));
1170 
1171   // Create a file under the directory with wider permissions.
1172   FilePath file_name_to =
1173       dir_name_to.Append(FILE_PATH_LITERAL("Reggy-1.txt"));
1174   CreateTextFile(file_name_to, L"Rigby");
1175   ASSERT_TRUE(PathExists(file_name_to));
1176   ASSERT_TRUE(SetPosixFilePermissions(file_name_to, 0777));
1177 
1178   // Ensure that when we copy the directory, the file contents are copied
1179   // but the permissions on the destination are left alone.
1180   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
1181   ASSERT_TRUE(PathExists(file_name_to));
1182   ASSERT_EQ(L"Mordecai", ReadTextFile(file_name_to));
1183 
1184   int mode = 0;
1185   ASSERT_TRUE(GetPosixFilePermissions(file_name_to, &mode));
1186   EXPECT_EQ(0777, mode);
1187 }
1188 
TEST_F(FileUtilTest,CopyDirectoryExclDoesNotOverwrite)1189 TEST_F(FileUtilTest, CopyDirectoryExclDoesNotOverwrite) {
1190   // Create source directory.
1191   FilePath dir_name_from =
1192       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1193   CreateDirectory(dir_name_from);
1194   ASSERT_TRUE(PathExists(dir_name_from));
1195 
1196   // Create a file under the directory.
1197   FilePath file_name_from =
1198       dir_name_from.Append(FILE_PATH_LITERAL("Reggy-1.txt"));
1199   CreateTextFile(file_name_from, L"Mordecai");
1200   ASSERT_TRUE(PathExists(file_name_from));
1201 
1202   // Create destination directory.
1203   FilePath dir_name_to =
1204       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1205   CreateDirectory(dir_name_to);
1206   ASSERT_TRUE(PathExists(dir_name_to));
1207 
1208   // Create a file under the directory with the same name.
1209   FilePath file_name_to = dir_name_to.Append(FILE_PATH_LITERAL("Reggy-1.txt"));
1210   CreateTextFile(file_name_to, L"Rigby");
1211   ASSERT_TRUE(PathExists(file_name_to));
1212 
1213   // Ensure that copying failed and the file was not overwritten.
1214   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
1215   ASSERT_TRUE(PathExists(file_name_to));
1216   ASSERT_EQ(L"Rigby", ReadTextFile(file_name_to));
1217 }
1218 
TEST_F(FileUtilTest,CopyDirectoryExclDirectoryOverExistingFile)1219 TEST_F(FileUtilTest, CopyDirectoryExclDirectoryOverExistingFile) {
1220   // Create source directory.
1221   FilePath dir_name_from =
1222       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1223   CreateDirectory(dir_name_from);
1224   ASSERT_TRUE(PathExists(dir_name_from));
1225 
1226   // Create a subdirectory.
1227   FilePath subdir_name_from = dir_name_from.Append(FILE_PATH_LITERAL("Subsub"));
1228   CreateDirectory(subdir_name_from);
1229   ASSERT_TRUE(PathExists(subdir_name_from));
1230 
1231   // Create destination directory.
1232   FilePath dir_name_to =
1233       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1234   CreateDirectory(dir_name_to);
1235   ASSERT_TRUE(PathExists(dir_name_to));
1236 
1237   // Create a regular file under the directory with the same name.
1238   FilePath file_name_to = dir_name_to.Append(FILE_PATH_LITERAL("Subsub"));
1239   CreateTextFile(file_name_to, L"Rigby");
1240   ASSERT_TRUE(PathExists(file_name_to));
1241 
1242   // Ensure that copying failed and the file was not overwritten.
1243   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
1244   ASSERT_TRUE(PathExists(file_name_to));
1245   ASSERT_EQ(L"Rigby", ReadTextFile(file_name_to));
1246 }
1247 
TEST_F(FileUtilTest,CopyDirectoryExclDirectoryOverExistingDirectory)1248 TEST_F(FileUtilTest, CopyDirectoryExclDirectoryOverExistingDirectory) {
1249   // Create source directory.
1250   FilePath dir_name_from =
1251       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1252   CreateDirectory(dir_name_from);
1253   ASSERT_TRUE(PathExists(dir_name_from));
1254 
1255   // Create a subdirectory.
1256   FilePath subdir_name_from = dir_name_from.Append(FILE_PATH_LITERAL("Subsub"));
1257   CreateDirectory(subdir_name_from);
1258   ASSERT_TRUE(PathExists(subdir_name_from));
1259 
1260   // Create destination directory.
1261   FilePath dir_name_to =
1262       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1263   CreateDirectory(dir_name_to);
1264   ASSERT_TRUE(PathExists(dir_name_to));
1265 
1266   // Create a subdirectory under the directory with the same name.
1267   FilePath subdir_name_to = dir_name_to.Append(FILE_PATH_LITERAL("Subsub"));
1268   CreateDirectory(subdir_name_to);
1269   ASSERT_TRUE(PathExists(subdir_name_to));
1270 
1271   // Ensure that copying failed and the file was not overwritten.
1272   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
1273 }
1274 
TEST_F(FileUtilTest,CopyFileExecutablePermission)1275 TEST_F(FileUtilTest, CopyFileExecutablePermission) {
1276   FilePath src = temp_dir_.GetPath().Append(FPL("src.txt"));
1277   const std::wstring file_contents(L"Gooooooooooooooooooooogle");
1278   CreateTextFile(src, file_contents);
1279 
1280   ASSERT_TRUE(SetPosixFilePermissions(src, 0755));
1281   int mode = 0;
1282   ASSERT_TRUE(GetPosixFilePermissions(src, &mode));
1283   EXPECT_EQ(0755, mode);
1284 
1285   FilePath dst = temp_dir_.GetPath().Append(FPL("dst.txt"));
1286   ASSERT_TRUE(CopyFile(src, dst));
1287   EXPECT_EQ(file_contents, ReadTextFile(dst));
1288 
1289   ASSERT_TRUE(GetPosixFilePermissions(dst, &mode));
1290   int expected_mode;
1291 #if defined(OS_MACOSX)
1292   expected_mode = 0755;
1293 #elif defined(OS_CHROMEOS)
1294   expected_mode = 0644;
1295 #else
1296   expected_mode = 0600;
1297 #endif
1298   EXPECT_EQ(expected_mode, mode);
1299   ASSERT_TRUE(DeleteFile(dst, false));
1300 
1301   ASSERT_TRUE(SetPosixFilePermissions(src, 0777));
1302   ASSERT_TRUE(GetPosixFilePermissions(src, &mode));
1303   EXPECT_EQ(0777, mode);
1304 
1305   ASSERT_TRUE(CopyFile(src, dst));
1306   EXPECT_EQ(file_contents, ReadTextFile(dst));
1307 
1308   ASSERT_TRUE(GetPosixFilePermissions(dst, &mode));
1309 #if defined(OS_MACOSX)
1310   expected_mode = 0755;
1311 #elif defined(OS_CHROMEOS)
1312   expected_mode = 0644;
1313 #else
1314   expected_mode = 0600;
1315 #endif
1316   EXPECT_EQ(expected_mode, mode);
1317   ASSERT_TRUE(DeleteFile(dst, false));
1318 
1319   ASSERT_TRUE(SetPosixFilePermissions(src, 0400));
1320   ASSERT_TRUE(GetPosixFilePermissions(src, &mode));
1321   EXPECT_EQ(0400, mode);
1322 
1323   ASSERT_TRUE(CopyFile(src, dst));
1324   EXPECT_EQ(file_contents, ReadTextFile(dst));
1325 
1326   ASSERT_TRUE(GetPosixFilePermissions(dst, &mode));
1327 #if defined(OS_MACOSX)
1328   expected_mode = 0600;
1329 #elif defined(OS_CHROMEOS)
1330   expected_mode = 0644;
1331 #else
1332   expected_mode = 0600;
1333 #endif
1334   EXPECT_EQ(expected_mode, mode);
1335 
1336   // This time, do not delete |dst|. Instead set its permissions to 0777.
1337   ASSERT_TRUE(SetPosixFilePermissions(dst, 0777));
1338   ASSERT_TRUE(GetPosixFilePermissions(dst, &mode));
1339   EXPECT_EQ(0777, mode);
1340 
1341   // Overwrite it and check the permissions again.
1342   ASSERT_TRUE(CopyFile(src, dst));
1343   EXPECT_EQ(file_contents, ReadTextFile(dst));
1344   ASSERT_TRUE(GetPosixFilePermissions(dst, &mode));
1345   EXPECT_EQ(0777, mode);
1346 }
1347 
1348 #endif  // defined(OS_POSIX)
1349 
1350 #if !defined(OS_FUCHSIA)
1351 
TEST_F(FileUtilTest,CopyFileACL)1352 TEST_F(FileUtilTest, CopyFileACL) {
1353   // While FileUtilTest.CopyFile asserts the content is correctly copied over,
1354   // this test case asserts the access control bits are meeting expectations in
1355   // CopyFile().
1356   FilePath src = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("src.txt"));
1357   const std::wstring file_contents(L"Gooooooooooooooooooooogle");
1358   CreateTextFile(src, file_contents);
1359 
1360   // Set the source file to read-only.
1361   ASSERT_FALSE(IsReadOnly(src));
1362   SetReadOnly(src, true);
1363   ASSERT_TRUE(IsReadOnly(src));
1364 
1365   // Copy the file.
1366   FilePath dst = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("dst.txt"));
1367   ASSERT_TRUE(CopyFile(src, dst));
1368   EXPECT_EQ(file_contents, ReadTextFile(dst));
1369 
1370   ASSERT_FALSE(IsReadOnly(dst));
1371 }
1372 
TEST_F(FileUtilTest,CopyDirectoryACL)1373 TEST_F(FileUtilTest, CopyDirectoryACL) {
1374   // Create source directories.
1375   FilePath src = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("src"));
1376   FilePath src_subdir = src.Append(FILE_PATH_LITERAL("subdir"));
1377   CreateDirectory(src_subdir);
1378   ASSERT_TRUE(PathExists(src_subdir));
1379 
1380   // Create a file under the directory.
1381   FilePath src_file = src.Append(FILE_PATH_LITERAL("src.txt"));
1382   CreateTextFile(src_file, L"Gooooooooooooooooooooogle");
1383   SetReadOnly(src_file, true);
1384   ASSERT_TRUE(IsReadOnly(src_file));
1385 
1386   // Make directory read-only.
1387   SetReadOnly(src_subdir, true);
1388   ASSERT_TRUE(IsReadOnly(src_subdir));
1389 
1390   // Copy the directory recursively.
1391   FilePath dst = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("dst"));
1392   FilePath dst_file = dst.Append(FILE_PATH_LITERAL("src.txt"));
1393   EXPECT_TRUE(CopyDirectory(src, dst, true));
1394 
1395   FilePath dst_subdir = dst.Append(FILE_PATH_LITERAL("subdir"));
1396   ASSERT_FALSE(IsReadOnly(dst_subdir));
1397   ASSERT_FALSE(IsReadOnly(dst_file));
1398 
1399   // Give write permissions to allow deletion.
1400   SetReadOnly(src_subdir, false);
1401   ASSERT_FALSE(IsReadOnly(src_subdir));
1402 }
1403 
1404 #endif  // !defined(OS_FUCHSIA)
1405 
TEST_F(FileUtilTest,DeleteNonExistent)1406 TEST_F(FileUtilTest, DeleteNonExistent) {
1407   FilePath non_existent =
1408       temp_dir_.GetPath().AppendASCII("bogus_file_dne.foobar");
1409   ASSERT_FALSE(PathExists(non_existent));
1410 
1411   EXPECT_TRUE(DeleteFile(non_existent, false));
1412   ASSERT_FALSE(PathExists(non_existent));
1413   EXPECT_TRUE(DeleteFileRecursively(non_existent));
1414   ASSERT_FALSE(PathExists(non_existent));
1415 }
1416 
TEST_F(FileUtilTest,DeleteNonExistentWithNonExistentParent)1417 TEST_F(FileUtilTest, DeleteNonExistentWithNonExistentParent) {
1418   FilePath non_existent = temp_dir_.GetPath().AppendASCII("bogus_topdir");
1419   non_existent = non_existent.AppendASCII("bogus_subdir");
1420   ASSERT_FALSE(PathExists(non_existent));
1421 
1422   EXPECT_TRUE(DeleteFile(non_existent, false));
1423   ASSERT_FALSE(PathExists(non_existent));
1424   EXPECT_TRUE(DeleteFileRecursively(non_existent));
1425   ASSERT_FALSE(PathExists(non_existent));
1426 }
1427 
TEST_F(FileUtilTest,DeleteFile)1428 TEST_F(FileUtilTest, DeleteFile) {
1429   // Create a file
1430   FilePath file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 1.txt"));
1431   CreateTextFile(file_name, bogus_content);
1432   ASSERT_TRUE(PathExists(file_name));
1433 
1434   // Make sure it's deleted
1435   EXPECT_TRUE(DeleteFile(file_name, false));
1436   EXPECT_FALSE(PathExists(file_name));
1437 
1438   // Test recursive case, create a new file
1439   file_name = temp_dir_.GetPath().Append(FPL("Test DeleteFile 2.txt"));
1440   CreateTextFile(file_name, bogus_content);
1441   ASSERT_TRUE(PathExists(file_name));
1442 
1443   // Make sure it's deleted
1444   EXPECT_TRUE(DeleteFileRecursively(file_name));
1445   EXPECT_FALSE(PathExists(file_name));
1446 }
1447 
1448 #if defined(OS_ANDROID)
TEST_F(FileUtilTest,DeleteContentUri)1449 TEST_F(FileUtilTest, DeleteContentUri) {
1450   // Get the path to the test file.
1451   FilePath data_dir;
1452   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
1453   data_dir = data_dir.Append(FPL("file_util"));
1454   ASSERT_TRUE(PathExists(data_dir));
1455   FilePath image_file = data_dir.Append(FPL("red.png"));
1456   ASSERT_TRUE(PathExists(image_file));
1457 
1458   // Make a copy (we don't want to delete the original red.png when deleting the
1459   // content URI).
1460   FilePath image_copy = data_dir.Append(FPL("redcopy.png"));
1461   ASSERT_TRUE(CopyFile(image_file, image_copy));
1462 
1463   // Insert the image into MediaStore and get a content URI.
1464   FilePath uri_path = InsertImageIntoMediaStore(image_copy);
1465   ASSERT_TRUE(uri_path.IsContentUri());
1466   ASSERT_TRUE(PathExists(uri_path));
1467 
1468   // Try deleting the content URI.
1469   EXPECT_TRUE(DeleteFile(uri_path, false));
1470   EXPECT_FALSE(PathExists(image_copy));
1471   EXPECT_FALSE(PathExists(uri_path));
1472 }
1473 #endif  // defined(OS_ANDROID)
1474 
1475 #if defined(OS_WIN)
1476 // Tests that the Delete function works for wild cards, especially
1477 // with the recursion flag.  Also coincidentally tests PathExists.
1478 // TODO(erikkay): see if anyone's actually using this feature of the API
TEST_F(FileUtilTest,DeleteWildCard)1479 TEST_F(FileUtilTest, DeleteWildCard) {
1480   // Create a file and a directory
1481   FilePath file_name =
1482       temp_dir_.GetPath().Append(FPL("Test DeleteWildCard.txt"));
1483   CreateTextFile(file_name, bogus_content);
1484   ASSERT_TRUE(PathExists(file_name));
1485 
1486   FilePath subdir_path = temp_dir_.GetPath().Append(FPL("DeleteWildCardDir"));
1487   CreateDirectory(subdir_path);
1488   ASSERT_TRUE(PathExists(subdir_path));
1489 
1490   // Create the wildcard path
1491   FilePath directory_contents = temp_dir_.GetPath();
1492   directory_contents = directory_contents.Append(FPL("*"));
1493 
1494   // Delete non-recursively and check that only the file is deleted
1495   EXPECT_TRUE(DeleteFile(directory_contents, false));
1496   EXPECT_FALSE(PathExists(file_name));
1497   EXPECT_TRUE(PathExists(subdir_path));
1498 
1499   // Delete recursively and make sure all contents are deleted
1500   EXPECT_TRUE(DeleteFileRecursively(directory_contents));
1501   EXPECT_FALSE(PathExists(file_name));
1502   EXPECT_FALSE(PathExists(subdir_path));
1503 }
1504 
1505 // TODO(erikkay): see if anyone's actually using this feature of the API
TEST_F(FileUtilTest,DeleteNonExistantWildCard)1506 TEST_F(FileUtilTest, DeleteNonExistantWildCard) {
1507   // Create a file and a directory
1508   FilePath subdir_path =
1509       temp_dir_.GetPath().Append(FPL("DeleteNonExistantWildCard"));
1510   CreateDirectory(subdir_path);
1511   ASSERT_TRUE(PathExists(subdir_path));
1512 
1513   // Create the wildcard path
1514   FilePath directory_contents = subdir_path;
1515   directory_contents = directory_contents.Append(FPL("*"));
1516 
1517   // Delete non-recursively and check nothing got deleted
1518   EXPECT_TRUE(DeleteFile(directory_contents, false));
1519   EXPECT_TRUE(PathExists(subdir_path));
1520 
1521   // Delete recursively and check nothing got deleted
1522   EXPECT_TRUE(DeleteFileRecursively(directory_contents));
1523   EXPECT_TRUE(PathExists(subdir_path));
1524 }
1525 #endif
1526 
1527 // Tests non-recursive Delete() for a directory.
TEST_F(FileUtilTest,DeleteDirNonRecursive)1528 TEST_F(FileUtilTest, DeleteDirNonRecursive) {
1529   // Create a subdirectory and put a file and two directories inside.
1530   FilePath test_subdir =
1531       temp_dir_.GetPath().Append(FPL("DeleteDirNonRecursive"));
1532   CreateDirectory(test_subdir);
1533   ASSERT_TRUE(PathExists(test_subdir));
1534 
1535   FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt"));
1536   CreateTextFile(file_name, bogus_content);
1537   ASSERT_TRUE(PathExists(file_name));
1538 
1539   FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
1540   CreateDirectory(subdir_path1);
1541   ASSERT_TRUE(PathExists(subdir_path1));
1542 
1543   FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
1544   CreateDirectory(subdir_path2);
1545   ASSERT_TRUE(PathExists(subdir_path2));
1546 
1547   // Delete non-recursively and check that the empty dir got deleted
1548   EXPECT_TRUE(DeleteFile(subdir_path2, false));
1549   EXPECT_FALSE(PathExists(subdir_path2));
1550 
1551   // Delete non-recursively and check that nothing got deleted
1552   EXPECT_FALSE(DeleteFile(test_subdir, false));
1553   EXPECT_TRUE(PathExists(test_subdir));
1554   EXPECT_TRUE(PathExists(file_name));
1555   EXPECT_TRUE(PathExists(subdir_path1));
1556 }
1557 
1558 // Tests recursive Delete() for a directory.
TEST_F(FileUtilTest,DeleteDirRecursive)1559 TEST_F(FileUtilTest, DeleteDirRecursive) {
1560   // Create a subdirectory and put a file and two directories inside.
1561   FilePath test_subdir = temp_dir_.GetPath().Append(FPL("DeleteDirRecursive"));
1562   CreateDirectory(test_subdir);
1563   ASSERT_TRUE(PathExists(test_subdir));
1564 
1565   FilePath file_name = test_subdir.Append(FPL("Test DeleteDirRecursive.txt"));
1566   CreateTextFile(file_name, bogus_content);
1567   ASSERT_TRUE(PathExists(file_name));
1568 
1569   FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
1570   CreateDirectory(subdir_path1);
1571   ASSERT_TRUE(PathExists(subdir_path1));
1572 
1573   FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
1574   CreateDirectory(subdir_path2);
1575   ASSERT_TRUE(PathExists(subdir_path2));
1576 
1577   // Delete recursively and check that the empty dir got deleted
1578   EXPECT_TRUE(DeleteFileRecursively(subdir_path2));
1579   EXPECT_FALSE(PathExists(subdir_path2));
1580 
1581   // Delete recursively and check that everything got deleted
1582   EXPECT_TRUE(DeleteFileRecursively(test_subdir));
1583   EXPECT_FALSE(PathExists(file_name));
1584   EXPECT_FALSE(PathExists(subdir_path1));
1585   EXPECT_FALSE(PathExists(test_subdir));
1586 }
1587 
1588 // Tests recursive Delete() for a directory.
TEST_F(FileUtilTest,DeleteDirRecursiveWithOpenFile)1589 TEST_F(FileUtilTest, DeleteDirRecursiveWithOpenFile) {
1590   // Create a subdirectory and put a file and two directories inside.
1591   FilePath test_subdir = temp_dir_.GetPath().Append(FPL("DeleteWithOpenFile"));
1592   CreateDirectory(test_subdir);
1593   ASSERT_TRUE(PathExists(test_subdir));
1594 
1595   FilePath file_name1 = test_subdir.Append(FPL("Undeletebable File1.txt"));
1596   File file1(file_name1,
1597              File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
1598   ASSERT_TRUE(PathExists(file_name1));
1599 
1600   FilePath file_name2 = test_subdir.Append(FPL("Deleteable File2.txt"));
1601   CreateTextFile(file_name2, bogus_content);
1602   ASSERT_TRUE(PathExists(file_name2));
1603 
1604   FilePath file_name3 = test_subdir.Append(FPL("Undeletebable File3.txt"));
1605   File file3(file_name3,
1606              File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
1607   ASSERT_TRUE(PathExists(file_name3));
1608 
1609 #if defined(OS_LINUX)
1610   // On Windows, holding the file open in sufficient to make it un-deletable.
1611   // The POSIX code is verifiable on Linux by creating an "immutable" file but
1612   // this is best-effort because it's not supported by all file systems. Both
1613   // files will have the same flags so no need to get them individually.
1614   int flags;
1615   bool file_attrs_supported =
1616       ioctl(file1.GetPlatformFile(), FS_IOC_GETFLAGS, &flags) == 0;
1617   // Some filesystems (e.g. tmpfs) don't support file attributes.
1618   if (file_attrs_supported) {
1619     flags |= FS_IMMUTABLE_FL;
1620     ioctl(file1.GetPlatformFile(), FS_IOC_SETFLAGS, &flags);
1621     ioctl(file3.GetPlatformFile(), FS_IOC_SETFLAGS, &flags);
1622   }
1623 #endif
1624 
1625   // Delete recursively and check that at least the second file got deleted.
1626   // This ensures that un-deletable files don't impact those that can be.
1627   DeleteFileRecursively(test_subdir);
1628   EXPECT_FALSE(PathExists(file_name2));
1629 
1630 #if defined(OS_LINUX)
1631   // Make sure that the test can clean up after itself.
1632   if (file_attrs_supported) {
1633     flags &= ~FS_IMMUTABLE_FL;
1634     ioctl(file1.GetPlatformFile(), FS_IOC_SETFLAGS, &flags);
1635     ioctl(file3.GetPlatformFile(), FS_IOC_SETFLAGS, &flags);
1636   }
1637 #endif
1638 }
1639 
TEST_F(FileUtilTest,MoveFileNew)1640 TEST_F(FileUtilTest, MoveFileNew) {
1641   // Create a file
1642   FilePath file_name_from =
1643       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1644   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1645   ASSERT_TRUE(PathExists(file_name_from));
1646 
1647   // The destination.
1648   FilePath file_name_to = temp_dir_.GetPath().Append(
1649       FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
1650   ASSERT_FALSE(PathExists(file_name_to));
1651 
1652   EXPECT_TRUE(Move(file_name_from, file_name_to));
1653 
1654   // Check everything has been moved.
1655   EXPECT_FALSE(PathExists(file_name_from));
1656   EXPECT_TRUE(PathExists(file_name_to));
1657 }
1658 
TEST_F(FileUtilTest,MoveFileExists)1659 TEST_F(FileUtilTest, MoveFileExists) {
1660   // Create a file
1661   FilePath file_name_from =
1662       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1663   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1664   ASSERT_TRUE(PathExists(file_name_from));
1665 
1666   // The destination name.
1667   FilePath file_name_to = temp_dir_.GetPath().Append(
1668       FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
1669   CreateTextFile(file_name_to, L"Old file content");
1670   ASSERT_TRUE(PathExists(file_name_to));
1671 
1672   EXPECT_TRUE(Move(file_name_from, file_name_to));
1673 
1674   // Check everything has been moved.
1675   EXPECT_FALSE(PathExists(file_name_from));
1676   EXPECT_TRUE(PathExists(file_name_to));
1677   EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
1678 }
1679 
TEST_F(FileUtilTest,MoveFileDirExists)1680 TEST_F(FileUtilTest, MoveFileDirExists) {
1681   // Create a file
1682   FilePath file_name_from =
1683       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1684   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1685   ASSERT_TRUE(PathExists(file_name_from));
1686 
1687   // The destination directory
1688   FilePath dir_name_to =
1689       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Destination"));
1690   CreateDirectory(dir_name_to);
1691   ASSERT_TRUE(PathExists(dir_name_to));
1692 
1693   EXPECT_FALSE(Move(file_name_from, dir_name_to));
1694 }
1695 
1696 
TEST_F(FileUtilTest,MoveNew)1697 TEST_F(FileUtilTest, MoveNew) {
1698   // Create a directory
1699   FilePath dir_name_from =
1700       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1701   CreateDirectory(dir_name_from);
1702   ASSERT_TRUE(PathExists(dir_name_from));
1703 
1704   // Create a file under the directory
1705   FilePath txt_file_name(FILE_PATH_LITERAL("Move_Test_File.txt"));
1706   FilePath file_name_from = dir_name_from.Append(txt_file_name);
1707   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1708   ASSERT_TRUE(PathExists(file_name_from));
1709 
1710   // Move the directory.
1711   FilePath dir_name_to =
1712       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1713   FilePath file_name_to =
1714       dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1715 
1716   ASSERT_FALSE(PathExists(dir_name_to));
1717 
1718   EXPECT_TRUE(Move(dir_name_from, dir_name_to));
1719 
1720   // Check everything has been moved.
1721   EXPECT_FALSE(PathExists(dir_name_from));
1722   EXPECT_FALSE(PathExists(file_name_from));
1723   EXPECT_TRUE(PathExists(dir_name_to));
1724   EXPECT_TRUE(PathExists(file_name_to));
1725 
1726   // Test path traversal.
1727   file_name_from = dir_name_to.Append(txt_file_name);
1728   file_name_to = dir_name_to.Append(FILE_PATH_LITERAL(".."));
1729   file_name_to = file_name_to.Append(txt_file_name);
1730   EXPECT_FALSE(Move(file_name_from, file_name_to));
1731   EXPECT_TRUE(PathExists(file_name_from));
1732   EXPECT_FALSE(PathExists(file_name_to));
1733   EXPECT_TRUE(internal::MoveUnsafe(file_name_from, file_name_to));
1734   EXPECT_FALSE(PathExists(file_name_from));
1735   EXPECT_TRUE(PathExists(file_name_to));
1736 }
1737 
TEST_F(FileUtilTest,MoveExist)1738 TEST_F(FileUtilTest, MoveExist) {
1739   // Create a directory
1740   FilePath dir_name_from =
1741       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1742   CreateDirectory(dir_name_from);
1743   ASSERT_TRUE(PathExists(dir_name_from));
1744 
1745   // Create a file under the directory
1746   FilePath file_name_from =
1747       dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1748   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1749   ASSERT_TRUE(PathExists(file_name_from));
1750 
1751   // Move the directory
1752   FilePath dir_name_exists =
1753       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Destination"));
1754 
1755   FilePath dir_name_to =
1756       dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir"));
1757   FilePath file_name_to =
1758       dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
1759 
1760   // Create the destination directory.
1761   CreateDirectory(dir_name_exists);
1762   ASSERT_TRUE(PathExists(dir_name_exists));
1763 
1764   EXPECT_TRUE(Move(dir_name_from, dir_name_to));
1765 
1766   // Check everything has been moved.
1767   EXPECT_FALSE(PathExists(dir_name_from));
1768   EXPECT_FALSE(PathExists(file_name_from));
1769   EXPECT_TRUE(PathExists(dir_name_to));
1770   EXPECT_TRUE(PathExists(file_name_to));
1771 }
1772 
TEST_F(FileUtilTest,CopyDirectoryRecursivelyNew)1773 TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) {
1774   // Create a directory.
1775   FilePath dir_name_from =
1776       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1777   CreateDirectory(dir_name_from);
1778   ASSERT_TRUE(PathExists(dir_name_from));
1779 
1780   // Create a file under the directory.
1781   FilePath file_name_from =
1782       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1783   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1784   ASSERT_TRUE(PathExists(file_name_from));
1785 
1786   // Create a subdirectory.
1787   FilePath subdir_name_from =
1788       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1789   CreateDirectory(subdir_name_from);
1790   ASSERT_TRUE(PathExists(subdir_name_from));
1791 
1792   // Create a file under the subdirectory.
1793   FilePath file_name2_from =
1794       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1795   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1796   ASSERT_TRUE(PathExists(file_name2_from));
1797 
1798   // Copy the directory recursively.
1799   FilePath dir_name_to =
1800       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1801   FilePath file_name_to =
1802       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1803   FilePath subdir_name_to =
1804       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1805   FilePath file_name2_to =
1806       subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1807 
1808   ASSERT_FALSE(PathExists(dir_name_to));
1809 
1810   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, true));
1811 
1812   // Check everything has been copied.
1813   EXPECT_TRUE(PathExists(dir_name_from));
1814   EXPECT_TRUE(PathExists(file_name_from));
1815   EXPECT_TRUE(PathExists(subdir_name_from));
1816   EXPECT_TRUE(PathExists(file_name2_from));
1817   EXPECT_TRUE(PathExists(dir_name_to));
1818   EXPECT_TRUE(PathExists(file_name_to));
1819   EXPECT_TRUE(PathExists(subdir_name_to));
1820   EXPECT_TRUE(PathExists(file_name2_to));
1821 }
1822 
TEST_F(FileUtilTest,CopyDirectoryRecursivelyExists)1823 TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) {
1824   // Create a directory.
1825   FilePath dir_name_from =
1826       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1827   CreateDirectory(dir_name_from);
1828   ASSERT_TRUE(PathExists(dir_name_from));
1829 
1830   // Create a file under the directory.
1831   FilePath file_name_from =
1832       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1833   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1834   ASSERT_TRUE(PathExists(file_name_from));
1835 
1836   // Create a subdirectory.
1837   FilePath subdir_name_from =
1838       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1839   CreateDirectory(subdir_name_from);
1840   ASSERT_TRUE(PathExists(subdir_name_from));
1841 
1842   // Create a file under the subdirectory.
1843   FilePath file_name2_from =
1844       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1845   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1846   ASSERT_TRUE(PathExists(file_name2_from));
1847 
1848   // Copy the directory recursively.
1849   FilePath dir_name_exists =
1850       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Destination"));
1851 
1852   FilePath dir_name_to =
1853       dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1854   FilePath file_name_to =
1855       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1856   FilePath subdir_name_to =
1857       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1858   FilePath file_name2_to =
1859       subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1860 
1861   // Create the destination directory.
1862   CreateDirectory(dir_name_exists);
1863   ASSERT_TRUE(PathExists(dir_name_exists));
1864 
1865   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_exists, true));
1866 
1867   // Check everything has been copied.
1868   EXPECT_TRUE(PathExists(dir_name_from));
1869   EXPECT_TRUE(PathExists(file_name_from));
1870   EXPECT_TRUE(PathExists(subdir_name_from));
1871   EXPECT_TRUE(PathExists(file_name2_from));
1872   EXPECT_TRUE(PathExists(dir_name_to));
1873   EXPECT_TRUE(PathExists(file_name_to));
1874   EXPECT_TRUE(PathExists(subdir_name_to));
1875   EXPECT_TRUE(PathExists(file_name2_to));
1876 }
1877 
TEST_F(FileUtilTest,CopyDirectoryNew)1878 TEST_F(FileUtilTest, CopyDirectoryNew) {
1879   // Create a directory.
1880   FilePath dir_name_from =
1881       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1882   CreateDirectory(dir_name_from);
1883   ASSERT_TRUE(PathExists(dir_name_from));
1884 
1885   // Create a file under the directory.
1886   FilePath file_name_from =
1887       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1888   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1889   ASSERT_TRUE(PathExists(file_name_from));
1890 
1891   // Create a subdirectory.
1892   FilePath subdir_name_from =
1893       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1894   CreateDirectory(subdir_name_from);
1895   ASSERT_TRUE(PathExists(subdir_name_from));
1896 
1897   // Create a file under the subdirectory.
1898   FilePath file_name2_from =
1899       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1900   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1901   ASSERT_TRUE(PathExists(file_name2_from));
1902 
1903   // Copy the directory not recursively.
1904   FilePath dir_name_to =
1905       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1906   FilePath file_name_to =
1907       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1908   FilePath subdir_name_to =
1909       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1910 
1911   ASSERT_FALSE(PathExists(dir_name_to));
1912 
1913   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
1914 
1915   // Check everything has been copied.
1916   EXPECT_TRUE(PathExists(dir_name_from));
1917   EXPECT_TRUE(PathExists(file_name_from));
1918   EXPECT_TRUE(PathExists(subdir_name_from));
1919   EXPECT_TRUE(PathExists(file_name2_from));
1920   EXPECT_TRUE(PathExists(dir_name_to));
1921   EXPECT_TRUE(PathExists(file_name_to));
1922   EXPECT_FALSE(PathExists(subdir_name_to));
1923 }
1924 
TEST_F(FileUtilTest,CopyDirectoryExists)1925 TEST_F(FileUtilTest, CopyDirectoryExists) {
1926   // Create a directory.
1927   FilePath dir_name_from =
1928       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1929   CreateDirectory(dir_name_from);
1930   ASSERT_TRUE(PathExists(dir_name_from));
1931 
1932   // Create a file under the directory.
1933   FilePath file_name_from =
1934       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1935   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1936   ASSERT_TRUE(PathExists(file_name_from));
1937 
1938   // Create a subdirectory.
1939   FilePath subdir_name_from =
1940       dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1941   CreateDirectory(subdir_name_from);
1942   ASSERT_TRUE(PathExists(subdir_name_from));
1943 
1944   // Create a file under the subdirectory.
1945   FilePath file_name2_from =
1946       subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1947   CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1948   ASSERT_TRUE(PathExists(file_name2_from));
1949 
1950   // Copy the directory not recursively.
1951   FilePath dir_name_to =
1952       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
1953   FilePath file_name_to =
1954       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1955   FilePath subdir_name_to =
1956       dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
1957 
1958   // Create the destination directory.
1959   CreateDirectory(dir_name_to);
1960   ASSERT_TRUE(PathExists(dir_name_to));
1961 
1962   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
1963 
1964   // Check everything has been copied.
1965   EXPECT_TRUE(PathExists(dir_name_from));
1966   EXPECT_TRUE(PathExists(file_name_from));
1967   EXPECT_TRUE(PathExists(subdir_name_from));
1968   EXPECT_TRUE(PathExists(file_name2_from));
1969   EXPECT_TRUE(PathExists(dir_name_to));
1970   EXPECT_TRUE(PathExists(file_name_to));
1971   EXPECT_FALSE(PathExists(subdir_name_to));
1972 }
1973 
TEST_F(FileUtilTest,CopyFileWithCopyDirectoryRecursiveToNew)1974 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) {
1975   // Create a file
1976   FilePath file_name_from =
1977       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1978   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1979   ASSERT_TRUE(PathExists(file_name_from));
1980 
1981   // The destination name
1982   FilePath file_name_to = temp_dir_.GetPath().Append(
1983       FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1984   ASSERT_FALSE(PathExists(file_name_to));
1985 
1986   EXPECT_TRUE(CopyDirectory(file_name_from, file_name_to, true));
1987 
1988   // Check the has been copied
1989   EXPECT_TRUE(PathExists(file_name_to));
1990 }
1991 
TEST_F(FileUtilTest,CopyFileWithCopyDirectoryRecursiveToExisting)1992 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) {
1993   // Create a file
1994   FilePath file_name_from =
1995       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
1996   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1997   ASSERT_TRUE(PathExists(file_name_from));
1998 
1999   // The destination name
2000   FilePath file_name_to = temp_dir_.GetPath().Append(
2001       FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
2002   CreateTextFile(file_name_to, L"Old file content");
2003   ASSERT_TRUE(PathExists(file_name_to));
2004 
2005   EXPECT_TRUE(CopyDirectory(file_name_from, file_name_to, true));
2006 
2007   // Check the has been copied
2008   EXPECT_TRUE(PathExists(file_name_to));
2009   EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
2010 }
2011 
TEST_F(FileUtilTest,CopyFileWithCopyDirectoryRecursiveToExistingDirectory)2012 TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) {
2013   // Create a file
2014   FilePath file_name_from =
2015       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2016   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2017   ASSERT_TRUE(PathExists(file_name_from));
2018 
2019   // The destination
2020   FilePath dir_name_to =
2021       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Destination"));
2022   CreateDirectory(dir_name_to);
2023   ASSERT_TRUE(PathExists(dir_name_to));
2024   FilePath file_name_to =
2025       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2026 
2027   EXPECT_TRUE(CopyDirectory(file_name_from, dir_name_to, true));
2028 
2029   // Check the has been copied
2030   EXPECT_TRUE(PathExists(file_name_to));
2031 }
2032 
TEST_F(FileUtilTest,CopyFileFailureWithCopyDirectoryExcl)2033 TEST_F(FileUtilTest, CopyFileFailureWithCopyDirectoryExcl) {
2034   // Create a file
2035   FilePath file_name_from =
2036       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2037   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2038   ASSERT_TRUE(PathExists(file_name_from));
2039 
2040   // Make a destination file.
2041   FilePath file_name_to = temp_dir_.GetPath().Append(
2042       FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
2043   CreateTextFile(file_name_to, L"Old file content");
2044   ASSERT_TRUE(PathExists(file_name_to));
2045 
2046   // Overwriting the destination should fail.
2047   EXPECT_FALSE(CopyDirectoryExcl(file_name_from, file_name_to, true));
2048   EXPECT_EQ(L"Old file content", ReadTextFile(file_name_to));
2049 }
2050 
TEST_F(FileUtilTest,CopyDirectoryWithTrailingSeparators)2051 TEST_F(FileUtilTest, CopyDirectoryWithTrailingSeparators) {
2052   // Create a directory.
2053   FilePath dir_name_from =
2054       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2055   CreateDirectory(dir_name_from);
2056   ASSERT_TRUE(PathExists(dir_name_from));
2057 
2058   // Create a file under the directory.
2059   FilePath file_name_from =
2060       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2061   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2062   ASSERT_TRUE(PathExists(file_name_from));
2063 
2064   // Copy the directory recursively.
2065   FilePath dir_name_to =
2066       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2067   FilePath file_name_to =
2068       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2069 
2070   // Create from path with trailing separators.
2071 #if defined(OS_WIN)
2072   FilePath from_path =
2073       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\"));
2074 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
2075   FilePath from_path =
2076       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir///"));
2077 #endif
2078 
2079   EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true));
2080 
2081   // Check everything has been copied.
2082   EXPECT_TRUE(PathExists(dir_name_from));
2083   EXPECT_TRUE(PathExists(file_name_from));
2084   EXPECT_TRUE(PathExists(dir_name_to));
2085   EXPECT_TRUE(PathExists(file_name_to));
2086 }
2087 
2088 #if defined(OS_POSIX)
TEST_F(FileUtilTest,CopyDirectoryWithNonRegularFiles)2089 TEST_F(FileUtilTest, CopyDirectoryWithNonRegularFiles) {
2090   // Create a directory.
2091   FilePath dir_name_from =
2092       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2093   ASSERT_TRUE(CreateDirectory(dir_name_from));
2094   ASSERT_TRUE(PathExists(dir_name_from));
2095 
2096   // Create a file under the directory.
2097   FilePath file_name_from =
2098       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2099   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2100   ASSERT_TRUE(PathExists(file_name_from));
2101 
2102   // Create a symbolic link under the directory pointing to that file.
2103   FilePath symlink_name_from =
2104       dir_name_from.Append(FILE_PATH_LITERAL("Symlink"));
2105   ASSERT_TRUE(CreateSymbolicLink(file_name_from, symlink_name_from));
2106   ASSERT_TRUE(PathExists(symlink_name_from));
2107 
2108   // Create a fifo under the directory.
2109   FilePath fifo_name_from =
2110       dir_name_from.Append(FILE_PATH_LITERAL("Fifo"));
2111   ASSERT_EQ(0, mkfifo(fifo_name_from.value().c_str(), 0644));
2112   ASSERT_TRUE(PathExists(fifo_name_from));
2113 
2114   // Copy the directory.
2115   FilePath dir_name_to =
2116       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2117   FilePath file_name_to =
2118       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2119   FilePath symlink_name_to =
2120       dir_name_to.Append(FILE_PATH_LITERAL("Symlink"));
2121   FilePath fifo_name_to =
2122       dir_name_to.Append(FILE_PATH_LITERAL("Fifo"));
2123 
2124   ASSERT_FALSE(PathExists(dir_name_to));
2125 
2126   EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
2127 
2128   // Check that only directories and regular files are copied.
2129   EXPECT_TRUE(PathExists(dir_name_from));
2130   EXPECT_TRUE(PathExists(file_name_from));
2131   EXPECT_TRUE(PathExists(symlink_name_from));
2132   EXPECT_TRUE(PathExists(fifo_name_from));
2133   EXPECT_TRUE(PathExists(dir_name_to));
2134   EXPECT_TRUE(PathExists(file_name_to));
2135   EXPECT_FALSE(PathExists(symlink_name_to));
2136   EXPECT_FALSE(PathExists(fifo_name_to));
2137 }
2138 
TEST_F(FileUtilTest,CopyDirectoryExclFileOverSymlink)2139 TEST_F(FileUtilTest, CopyDirectoryExclFileOverSymlink) {
2140   // Create a directory.
2141   FilePath dir_name_from =
2142       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2143   ASSERT_TRUE(CreateDirectory(dir_name_from));
2144   ASSERT_TRUE(PathExists(dir_name_from));
2145 
2146   // Create a file under the directory.
2147   FilePath file_name_from =
2148       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2149   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2150   ASSERT_TRUE(PathExists(file_name_from));
2151 
2152   // Create a destination directory with a symlink of the same name.
2153   FilePath dir_name_to =
2154       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2155   ASSERT_TRUE(CreateDirectory(dir_name_to));
2156   ASSERT_TRUE(PathExists(dir_name_to));
2157 
2158   FilePath symlink_target =
2159       dir_name_to.Append(FILE_PATH_LITERAL("Symlink_Target.txt"));
2160   CreateTextFile(symlink_target, L"asdf");
2161   ASSERT_TRUE(PathExists(symlink_target));
2162 
2163   FilePath symlink_name_to =
2164       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2165   ASSERT_TRUE(CreateSymbolicLink(symlink_target, symlink_name_to));
2166   ASSERT_TRUE(PathExists(symlink_name_to));
2167 
2168   // Check that copying fails.
2169   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
2170 }
2171 
TEST_F(FileUtilTest,CopyDirectoryExclDirectoryOverSymlink)2172 TEST_F(FileUtilTest, CopyDirectoryExclDirectoryOverSymlink) {
2173   // Create a directory.
2174   FilePath dir_name_from =
2175       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2176   ASSERT_TRUE(CreateDirectory(dir_name_from));
2177   ASSERT_TRUE(PathExists(dir_name_from));
2178 
2179   // Create a subdirectory.
2180   FilePath subdir_name_from = dir_name_from.Append(FILE_PATH_LITERAL("Subsub"));
2181   CreateDirectory(subdir_name_from);
2182   ASSERT_TRUE(PathExists(subdir_name_from));
2183 
2184   // Create a destination directory with a symlink of the same name.
2185   FilePath dir_name_to =
2186       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2187   ASSERT_TRUE(CreateDirectory(dir_name_to));
2188   ASSERT_TRUE(PathExists(dir_name_to));
2189 
2190   FilePath symlink_target = dir_name_to.Append(FILE_PATH_LITERAL("Subsub"));
2191   CreateTextFile(symlink_target, L"asdf");
2192   ASSERT_TRUE(PathExists(symlink_target));
2193 
2194   FilePath symlink_name_to =
2195       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2196   ASSERT_TRUE(CreateSymbolicLink(symlink_target, symlink_name_to));
2197   ASSERT_TRUE(PathExists(symlink_name_to));
2198 
2199   // Check that copying fails.
2200   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
2201 }
2202 
TEST_F(FileUtilTest,CopyDirectoryExclFileOverDanglingSymlink)2203 TEST_F(FileUtilTest, CopyDirectoryExclFileOverDanglingSymlink) {
2204   // Create a directory.
2205   FilePath dir_name_from =
2206       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2207   ASSERT_TRUE(CreateDirectory(dir_name_from));
2208   ASSERT_TRUE(PathExists(dir_name_from));
2209 
2210   // Create a file under the directory.
2211   FilePath file_name_from =
2212       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2213   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2214   ASSERT_TRUE(PathExists(file_name_from));
2215 
2216   // Create a destination directory with a dangling symlink of the same name.
2217   FilePath dir_name_to =
2218       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2219   ASSERT_TRUE(CreateDirectory(dir_name_to));
2220   ASSERT_TRUE(PathExists(dir_name_to));
2221 
2222   FilePath symlink_target =
2223       dir_name_to.Append(FILE_PATH_LITERAL("Symlink_Target.txt"));
2224   CreateTextFile(symlink_target, L"asdf");
2225   ASSERT_TRUE(PathExists(symlink_target));
2226 
2227   FilePath symlink_name_to =
2228       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2229   ASSERT_TRUE(CreateSymbolicLink(symlink_target, symlink_name_to));
2230   ASSERT_TRUE(PathExists(symlink_name_to));
2231   ASSERT_TRUE(DeleteFile(symlink_target, false));
2232 
2233   // Check that copying fails and that no file was created for the symlink's
2234   // referent.
2235   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
2236   EXPECT_FALSE(PathExists(symlink_target));
2237 }
2238 
TEST_F(FileUtilTest,CopyDirectoryExclDirectoryOverDanglingSymlink)2239 TEST_F(FileUtilTest, CopyDirectoryExclDirectoryOverDanglingSymlink) {
2240   // Create a directory.
2241   FilePath dir_name_from =
2242       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2243   ASSERT_TRUE(CreateDirectory(dir_name_from));
2244   ASSERT_TRUE(PathExists(dir_name_from));
2245 
2246   // Create a subdirectory.
2247   FilePath subdir_name_from = dir_name_from.Append(FILE_PATH_LITERAL("Subsub"));
2248   CreateDirectory(subdir_name_from);
2249   ASSERT_TRUE(PathExists(subdir_name_from));
2250 
2251   // Create a destination directory with a dangling symlink of the same name.
2252   FilePath dir_name_to =
2253       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2254   ASSERT_TRUE(CreateDirectory(dir_name_to));
2255   ASSERT_TRUE(PathExists(dir_name_to));
2256 
2257   FilePath symlink_target =
2258       dir_name_to.Append(FILE_PATH_LITERAL("Symlink_Target.txt"));
2259   CreateTextFile(symlink_target, L"asdf");
2260   ASSERT_TRUE(PathExists(symlink_target));
2261 
2262   FilePath symlink_name_to =
2263       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2264   ASSERT_TRUE(CreateSymbolicLink(symlink_target, symlink_name_to));
2265   ASSERT_TRUE(PathExists(symlink_name_to));
2266   ASSERT_TRUE(DeleteFile(symlink_target, false));
2267 
2268   // Check that copying fails and that no directory was created for the
2269   // symlink's referent.
2270   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
2271   EXPECT_FALSE(PathExists(symlink_target));
2272 }
2273 
TEST_F(FileUtilTest,CopyDirectoryExclFileOverFifo)2274 TEST_F(FileUtilTest, CopyDirectoryExclFileOverFifo) {
2275   // Create a directory.
2276   FilePath dir_name_from =
2277       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2278   ASSERT_TRUE(CreateDirectory(dir_name_from));
2279   ASSERT_TRUE(PathExists(dir_name_from));
2280 
2281   // Create a file under the directory.
2282   FilePath file_name_from =
2283       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2284   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2285   ASSERT_TRUE(PathExists(file_name_from));
2286 
2287   // Create a destination directory with a fifo of the same name.
2288   FilePath dir_name_to =
2289       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
2290   ASSERT_TRUE(CreateDirectory(dir_name_to));
2291   ASSERT_TRUE(PathExists(dir_name_to));
2292 
2293   FilePath fifo_name_to =
2294       dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2295   ASSERT_EQ(0, mkfifo(fifo_name_to.value().c_str(), 0644));
2296   ASSERT_TRUE(PathExists(fifo_name_to));
2297 
2298   // Check that copying fails.
2299   EXPECT_FALSE(CopyDirectoryExcl(dir_name_from, dir_name_to, false));
2300 }
2301 #endif  // defined(OS_POSIX)
2302 
TEST_F(FileUtilTest,CopyFile)2303 TEST_F(FileUtilTest, CopyFile) {
2304   // Create a directory
2305   FilePath dir_name_from =
2306       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
2307   ASSERT_TRUE(CreateDirectory(dir_name_from));
2308   ASSERT_TRUE(DirectoryExists(dir_name_from));
2309 
2310   // Create a file under the directory
2311   FilePath file_name_from =
2312       dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
2313   const std::wstring file_contents(L"Gooooooooooooooooooooogle");
2314   CreateTextFile(file_name_from, file_contents);
2315   ASSERT_TRUE(PathExists(file_name_from));
2316 
2317   // Copy the file.
2318   FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt"));
2319   ASSERT_TRUE(CopyFile(file_name_from, dest_file));
2320 
2321   // Try to copy the file to another location using '..' in the path.
2322   FilePath dest_file2(dir_name_from);
2323   dest_file2 = dest_file2.AppendASCII("..");
2324   dest_file2 = dest_file2.AppendASCII("DestFile.txt");
2325   ASSERT_FALSE(CopyFile(file_name_from, dest_file2));
2326 
2327   FilePath dest_file2_test(dir_name_from);
2328   dest_file2_test = dest_file2_test.DirName();
2329   dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt");
2330 
2331   // Check expected copy results.
2332   EXPECT_TRUE(PathExists(file_name_from));
2333   EXPECT_TRUE(PathExists(dest_file));
2334   EXPECT_EQ(file_contents, ReadTextFile(dest_file));
2335   EXPECT_FALSE(PathExists(dest_file2_test));
2336   EXPECT_FALSE(PathExists(dest_file2));
2337 
2338   // Change |file_name_from| contents.
2339   const std::wstring new_file_contents(L"Moogle");
2340   CreateTextFile(file_name_from, new_file_contents);
2341   ASSERT_TRUE(PathExists(file_name_from));
2342   EXPECT_EQ(new_file_contents, ReadTextFile(file_name_from));
2343 
2344   // Overwrite |dest_file|.
2345   ASSERT_TRUE(CopyFile(file_name_from, dest_file));
2346   EXPECT_TRUE(PathExists(dest_file));
2347   EXPECT_EQ(new_file_contents, ReadTextFile(dest_file));
2348 
2349   // Create another directory.
2350   FilePath dest_dir = temp_dir_.GetPath().Append(FPL("dest_dir"));
2351   ASSERT_TRUE(CreateDirectory(dest_dir));
2352   EXPECT_TRUE(DirectoryExists(dest_dir));
2353   EXPECT_TRUE(IsDirectoryEmpty(dest_dir));
2354 
2355   // Make sure CopyFile() cannot overwrite a directory.
2356   ASSERT_FALSE(CopyFile(file_name_from, dest_dir));
2357   EXPECT_TRUE(DirectoryExists(dest_dir));
2358   EXPECT_TRUE(IsDirectoryEmpty(dest_dir));
2359 }
2360 
2361 // file_util winds up using autoreleased objects on the Mac, so this needs
2362 // to be a PlatformTest.
2363 typedef PlatformTest ReadOnlyFileUtilTest;
2364 
TEST_F(ReadOnlyFileUtilTest,ContentsEqual)2365 TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
2366   FilePath data_dir;
2367   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
2368   data_dir = data_dir.AppendASCII("file_util");
2369   ASSERT_TRUE(PathExists(data_dir));
2370 
2371   FilePath original_file =
2372       data_dir.Append(FILE_PATH_LITERAL("original.txt"));
2373   FilePath same_file =
2374       data_dir.Append(FILE_PATH_LITERAL("same.txt"));
2375   FilePath same_length_file =
2376       data_dir.Append(FILE_PATH_LITERAL("same_length.txt"));
2377   FilePath different_file =
2378       data_dir.Append(FILE_PATH_LITERAL("different.txt"));
2379   FilePath different_first_file =
2380       data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
2381   FilePath different_last_file =
2382       data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
2383   FilePath empty1_file =
2384       data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
2385   FilePath empty2_file =
2386       data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
2387   FilePath shortened_file =
2388       data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
2389   FilePath binary_file =
2390       data_dir.Append(FILE_PATH_LITERAL("binary_file.bin"));
2391   FilePath binary_file_same =
2392       data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin"));
2393   FilePath binary_file_diff =
2394       data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin"));
2395 
2396   EXPECT_TRUE(ContentsEqual(original_file, original_file));
2397   EXPECT_TRUE(ContentsEqual(original_file, same_file));
2398   EXPECT_FALSE(ContentsEqual(original_file, same_length_file));
2399   EXPECT_FALSE(ContentsEqual(original_file, different_file));
2400   EXPECT_FALSE(ContentsEqual(FilePath(FILE_PATH_LITERAL("bogusname")),
2401                              FilePath(FILE_PATH_LITERAL("bogusname"))));
2402   EXPECT_FALSE(ContentsEqual(original_file, different_first_file));
2403   EXPECT_FALSE(ContentsEqual(original_file, different_last_file));
2404   EXPECT_TRUE(ContentsEqual(empty1_file, empty2_file));
2405   EXPECT_FALSE(ContentsEqual(original_file, shortened_file));
2406   EXPECT_FALSE(ContentsEqual(shortened_file, original_file));
2407   EXPECT_TRUE(ContentsEqual(binary_file, binary_file_same));
2408   EXPECT_FALSE(ContentsEqual(binary_file, binary_file_diff));
2409 }
2410 
TEST_F(ReadOnlyFileUtilTest,TextContentsEqual)2411 TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) {
2412   FilePath data_dir;
2413   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
2414   data_dir = data_dir.AppendASCII("file_util");
2415   ASSERT_TRUE(PathExists(data_dir));
2416 
2417   FilePath original_file =
2418       data_dir.Append(FILE_PATH_LITERAL("original.txt"));
2419   FilePath same_file =
2420       data_dir.Append(FILE_PATH_LITERAL("same.txt"));
2421   FilePath crlf_file =
2422       data_dir.Append(FILE_PATH_LITERAL("crlf.txt"));
2423   FilePath shortened_file =
2424       data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
2425   FilePath different_file =
2426       data_dir.Append(FILE_PATH_LITERAL("different.txt"));
2427   FilePath different_first_file =
2428       data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
2429   FilePath different_last_file =
2430       data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
2431   FilePath first1_file =
2432       data_dir.Append(FILE_PATH_LITERAL("first1.txt"));
2433   FilePath first2_file =
2434       data_dir.Append(FILE_PATH_LITERAL("first2.txt"));
2435   FilePath empty1_file =
2436       data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
2437   FilePath empty2_file =
2438       data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
2439   FilePath blank_line_file =
2440       data_dir.Append(FILE_PATH_LITERAL("blank_line.txt"));
2441   FilePath blank_line_crlf_file =
2442       data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt"));
2443 
2444   EXPECT_TRUE(TextContentsEqual(original_file, same_file));
2445   EXPECT_TRUE(TextContentsEqual(original_file, crlf_file));
2446   EXPECT_FALSE(TextContentsEqual(original_file, shortened_file));
2447   EXPECT_FALSE(TextContentsEqual(original_file, different_file));
2448   EXPECT_FALSE(TextContentsEqual(original_file, different_first_file));
2449   EXPECT_FALSE(TextContentsEqual(original_file, different_last_file));
2450   EXPECT_FALSE(TextContentsEqual(first1_file, first2_file));
2451   EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file));
2452   EXPECT_FALSE(TextContentsEqual(original_file, empty1_file));
2453   EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file));
2454 }
2455 
2456 // We don't need equivalent functionality outside of Windows.
2457 #if defined(OS_WIN)
TEST_F(FileUtilTest,CopyAndDeleteDirectoryTest)2458 TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) {
2459   // Create a directory
2460   FilePath dir_name_from = temp_dir_.GetPath().Append(
2461       FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
2462   CreateDirectory(dir_name_from);
2463   ASSERT_TRUE(PathExists(dir_name_from));
2464 
2465   // Create a file under the directory
2466   FilePath file_name_from =
2467       dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
2468   CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
2469   ASSERT_TRUE(PathExists(file_name_from));
2470 
2471   // Move the directory by using CopyAndDeleteDirectory
2472   FilePath dir_name_to =
2473       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("CopyAndDelete_To_Subdir"));
2474   FilePath file_name_to =
2475       dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
2476 
2477   ASSERT_FALSE(PathExists(dir_name_to));
2478 
2479   EXPECT_TRUE(internal::CopyAndDeleteDirectory(dir_name_from,
2480                                                      dir_name_to));
2481 
2482   // Check everything has been moved.
2483   EXPECT_FALSE(PathExists(dir_name_from));
2484   EXPECT_FALSE(PathExists(file_name_from));
2485   EXPECT_TRUE(PathExists(dir_name_to));
2486   EXPECT_TRUE(PathExists(file_name_to));
2487 }
2488 
TEST_F(FileUtilTest,GetTempDirTest)2489 TEST_F(FileUtilTest, GetTempDirTest) {
2490   static const TCHAR* kTmpKey = _T("TMP");
2491   static const TCHAR* kTmpValues[] = {
2492     _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\")
2493   };
2494   // Save the original $TMP.
2495   size_t original_tmp_size;
2496   TCHAR* original_tmp;
2497   ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey));
2498   // original_tmp may be NULL.
2499 
2500   for (unsigned int i = 0; i < size(kTmpValues); ++i) {
2501     FilePath path;
2502     ::_tputenv_s(kTmpKey, kTmpValues[i]);
2503     GetTempDir(&path);
2504     EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] <<
2505         " result=" << path.value();
2506   }
2507 
2508   // Restore the original $TMP.
2509   if (original_tmp) {
2510     ::_tputenv_s(kTmpKey, original_tmp);
2511     free(original_tmp);
2512   } else {
2513     ::_tputenv_s(kTmpKey, _T(""));
2514   }
2515 }
2516 #endif  // OS_WIN
2517 
2518 // Test that files opened by OpenFile are not set up for inheritance into child
2519 // procs.
TEST_F(FileUtilTest,OpenFileNoInheritance)2520 TEST_F(FileUtilTest, OpenFileNoInheritance) {
2521   FilePath file_path(temp_dir_.GetPath().Append(FPL("a_file")));
2522 
2523 // Character set handling is leaking according to ASAN. http://crbug.com/883698
2524 #if defined(ADDRESS_SANITIZER)
2525   static constexpr const char* modes[] = {"wb", "r"};
2526 #else
2527   static constexpr const char* modes[] = {"wb", "r,ccs=UTF-8"};
2528 #endif
2529 
2530   for (const char* mode : modes) {
2531     SCOPED_TRACE(mode);
2532     ASSERT_NO_FATAL_FAILURE(CreateTextFile(file_path, L"Geepers"));
2533     FILE* file = OpenFile(file_path, mode);
2534     ASSERT_NE(nullptr, file);
2535     {
2536       ScopedClosureRunner file_closer(BindOnce(IgnoreResult(&CloseFile), file));
2537       bool is_inheritable = true;
2538       ASSERT_NO_FATAL_FAILURE(GetIsInheritable(file, &is_inheritable));
2539       EXPECT_FALSE(is_inheritable);
2540     }
2541     ASSERT_TRUE(DeleteFile(file_path, false));
2542   }
2543 }
2544 
TEST_F(FileUtilTest,CreateTemporaryFileTest)2545 TEST_F(FileUtilTest, CreateTemporaryFileTest) {
2546   FilePath temp_files[3];
2547   for (auto& i : temp_files) {
2548     ASSERT_TRUE(CreateTemporaryFile(&i));
2549     EXPECT_TRUE(PathExists(i));
2550     EXPECT_FALSE(DirectoryExists(i));
2551   }
2552   for (int i = 0; i < 3; i++)
2553     EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]);
2554   for (const auto& i : temp_files)
2555     EXPECT_TRUE(DeleteFile(i, false));
2556 }
2557 
TEST_F(FileUtilTest,CreateAndOpenTemporaryFileTest)2558 TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) {
2559   FilePath names[3];
2560   FILE* fps[3];
2561   int i;
2562 
2563   // Create; make sure they are open and exist.
2564   for (i = 0; i < 3; ++i) {
2565     fps[i] = CreateAndOpenTemporaryFile(&(names[i]));
2566     ASSERT_TRUE(fps[i]);
2567     EXPECT_TRUE(PathExists(names[i]));
2568   }
2569 
2570   // Make sure all names are unique.
2571   for (i = 0; i < 3; ++i) {
2572     EXPECT_FALSE(names[i] == names[(i+1)%3]);
2573   }
2574 
2575   // Close and delete.
2576   for (i = 0; i < 3; ++i) {
2577     EXPECT_TRUE(CloseFile(fps[i]));
2578     EXPECT_TRUE(DeleteFile(names[i], false));
2579   }
2580 }
2581 
TEST_F(FileUtilTest,GetUniquePathTest)2582 TEST_F(FileUtilTest, GetUniquePathTest) {
2583   // Create a unique temp directory and use it to generate a unique file path.
2584   base::ScopedTempDir temp_dir;
2585   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
2586   EXPECT_TRUE(temp_dir.IsValid());
2587   FilePath base_name(FILE_PATH_LITERAL("Unique_Base_Name.txt"));
2588   FilePath base_path = temp_dir.GetPath().Append(base_name);
2589   EXPECT_FALSE(PathExists(base_path));
2590 
2591   // GetUniquePath() should return unchanged path if file does not exist.
2592   EXPECT_EQ(base_path, GetUniquePath(base_path));
2593 
2594   // Create the file.
2595   {
2596     File file(base_path,
2597               File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
2598     EXPECT_TRUE(PathExists(base_path));
2599   }
2600 
2601   static const FilePath::CharType* const kExpectedNames[] = {
2602       FILE_PATH_LITERAL("Unique_Base_Name (1).txt"),
2603       FILE_PATH_LITERAL("Unique_Base_Name (2).txt"),
2604       FILE_PATH_LITERAL("Unique_Base_Name (3).txt"),
2605   };
2606 
2607   // Call GetUniquePath() three times against this existing file name.
2608   for (const FilePath::CharType* expected_name : kExpectedNames) {
2609     FilePath expected_path = temp_dir.GetPath().Append(expected_name);
2610     FilePath path = GetUniquePath(base_path);
2611     EXPECT_EQ(expected_path, path);
2612 
2613     // Verify that a file with this path indeed does not exist on the file
2614     // system.
2615     EXPECT_FALSE(PathExists(path));
2616 
2617     // Create the file so it exists for the next call to GetUniquePath() in the
2618     // loop.
2619     File file(path, File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
2620     EXPECT_TRUE(PathExists(path));
2621   }
2622 }
2623 
TEST_F(FileUtilTest,FileToFILE)2624 TEST_F(FileUtilTest, FileToFILE) {
2625   File file;
2626   FILE* stream = FileToFILE(std::move(file), "w");
2627   EXPECT_FALSE(stream);
2628 
2629   FilePath file_name = temp_dir_.GetPath().Append(FPL("The file.txt"));
2630   file = File(file_name, File::FLAG_CREATE | File::FLAG_WRITE);
2631   EXPECT_TRUE(file.IsValid());
2632 
2633   stream = FileToFILE(std::move(file), "w");
2634   EXPECT_TRUE(stream);
2635   EXPECT_FALSE(file.IsValid());
2636   EXPECT_TRUE(CloseFile(stream));
2637 }
2638 
TEST_F(FileUtilTest,CreateNewTempDirectoryTest)2639 TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
2640   FilePath temp_dir;
2641   ASSERT_TRUE(CreateNewTempDirectory(FilePath::StringType(), &temp_dir));
2642   EXPECT_TRUE(PathExists(temp_dir));
2643   EXPECT_TRUE(DeleteFile(temp_dir, false));
2644 }
2645 
TEST_F(FileUtilTest,CreateNewTemporaryDirInDirTest)2646 TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
2647   FilePath new_dir;
2648   ASSERT_TRUE(CreateTemporaryDirInDir(
2649       temp_dir_.GetPath(), FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"),
2650       &new_dir));
2651   EXPECT_TRUE(PathExists(new_dir));
2652   EXPECT_TRUE(temp_dir_.GetPath().IsParent(new_dir));
2653   EXPECT_TRUE(DeleteFile(new_dir, false));
2654 }
2655 
2656 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
TEST_F(FileUtilTest,GetShmemTempDirTest)2657 TEST_F(FileUtilTest, GetShmemTempDirTest) {
2658   FilePath dir;
2659   EXPECT_TRUE(GetShmemTempDir(false, &dir));
2660   EXPECT_TRUE(DirectoryExists(dir));
2661 }
2662 
TEST_F(FileUtilTest,AllocateFileRegionTest_ZeroOffset)2663 TEST_F(FileUtilTest, AllocateFileRegionTest_ZeroOffset) {
2664   const int kTestFileLength = 9;
2665   char test_data[] = "test_data";
2666   FilePath file_path = temp_dir_.GetPath().Append(
2667       FILE_PATH_LITERAL("allocate_file_region_test_zero_offset"));
2668   WriteFile(file_path, test_data, kTestFileLength);
2669 
2670   File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
2671                            base::File::FLAG_WRITE);
2672   ASSERT_TRUE(file.IsValid());
2673   ASSERT_EQ(file.GetLength(), kTestFileLength);
2674 
2675   const int kExtendedFileLength = 23;
2676   ASSERT_TRUE(AllocateFileRegion(&file, 0, kExtendedFileLength));
2677   EXPECT_EQ(file.GetLength(), kExtendedFileLength);
2678 
2679   char data_read[32];
2680   int bytes_read = file.Read(0, data_read, kExtendedFileLength);
2681   EXPECT_EQ(bytes_read, kExtendedFileLength);
2682   for (int i = 0; i < kTestFileLength; ++i)
2683     EXPECT_EQ(test_data[i], data_read[i]);
2684   for (int i = kTestFileLength; i < kExtendedFileLength; ++i)
2685     EXPECT_EQ(0, data_read[i]);
2686 }
2687 
TEST_F(FileUtilTest,AllocateFileRegionTest_NonZeroOffset)2688 TEST_F(FileUtilTest, AllocateFileRegionTest_NonZeroOffset) {
2689   const int kTestFileLength = 9;
2690   char test_data[] = "test_data";
2691   FilePath file_path = temp_dir_.GetPath().Append(
2692       FILE_PATH_LITERAL("allocate_file_region_test_non_zero_offset"));
2693   WriteFile(file_path, test_data, kTestFileLength);
2694 
2695   File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
2696                            base::File::FLAG_WRITE);
2697   ASSERT_TRUE(file.IsValid());
2698   ASSERT_EQ(file.GetLength(), kTestFileLength);
2699 
2700   const int kExtensionOffset = 5;
2701   const int kExtensionSize = 10;
2702   ASSERT_TRUE(AllocateFileRegion(&file, kExtensionOffset, kExtensionSize));
2703   const int kExtendedFileLength = kExtensionOffset + kExtensionSize;
2704   EXPECT_EQ(file.GetLength(), kExtendedFileLength);
2705 
2706   char data_read[32];
2707   int bytes_read = file.Read(0, data_read, kExtendedFileLength);
2708   EXPECT_EQ(bytes_read, kExtendedFileLength);
2709   for (int i = 0; i < kTestFileLength; ++i)
2710     EXPECT_EQ(test_data[i], data_read[i]);
2711   for (int i = kTestFileLength; i < kExtendedFileLength; ++i)
2712     EXPECT_EQ(0, data_read[i]);
2713 }
2714 
TEST_F(FileUtilTest,AllocateFileRegionTest_DontTruncate)2715 TEST_F(FileUtilTest, AllocateFileRegionTest_DontTruncate) {
2716   const int kTestFileLength = 9;
2717   char test_data[] = "test_data";
2718   FilePath file_path = temp_dir_.GetPath().Append(
2719       FILE_PATH_LITERAL("allocate_file_region_test_dont_truncate"));
2720   WriteFile(file_path, test_data, kTestFileLength);
2721 
2722   File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
2723                            base::File::FLAG_WRITE);
2724   ASSERT_TRUE(file.IsValid());
2725   ASSERT_EQ(file.GetLength(), kTestFileLength);
2726 
2727   const int kTruncatedFileLength = 4;
2728   ASSERT_TRUE(AllocateFileRegion(&file, 0, kTruncatedFileLength));
2729   EXPECT_EQ(file.GetLength(), kTestFileLength);
2730 }
2731 #endif
2732 
TEST_F(FileUtilTest,GetHomeDirTest)2733 TEST_F(FileUtilTest, GetHomeDirTest) {
2734 #if !defined(OS_ANDROID)  // Not implemented on Android.
2735   // We don't actually know what the home directory is supposed to be without
2736   // calling some OS functions which would just duplicate the implementation.
2737   // So here we just test that it returns something "reasonable".
2738   FilePath home = GetHomeDir();
2739   ASSERT_FALSE(home.empty());
2740   ASSERT_TRUE(home.IsAbsolute());
2741 #endif
2742 }
2743 
TEST_F(FileUtilTest,CreateDirectoryTest)2744 TEST_F(FileUtilTest, CreateDirectoryTest) {
2745   FilePath test_root =
2746       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("create_directory_test"));
2747 #if defined(OS_WIN)
2748   FilePath test_path =
2749       test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\"));
2750 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
2751   FilePath test_path =
2752       test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/"));
2753 #endif
2754 
2755   EXPECT_FALSE(PathExists(test_path));
2756   EXPECT_TRUE(CreateDirectory(test_path));
2757   EXPECT_TRUE(PathExists(test_path));
2758   // CreateDirectory returns true if the DirectoryExists returns true.
2759   EXPECT_TRUE(CreateDirectory(test_path));
2760 
2761   // Doesn't work to create it on top of a non-dir
2762   test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt"));
2763   EXPECT_FALSE(PathExists(test_path));
2764   CreateTextFile(test_path, L"test file");
2765   EXPECT_TRUE(PathExists(test_path));
2766   EXPECT_FALSE(CreateDirectory(test_path));
2767 
2768   EXPECT_TRUE(DeleteFileRecursively(test_root));
2769   EXPECT_FALSE(PathExists(test_root));
2770   EXPECT_FALSE(PathExists(test_path));
2771 
2772   // Verify assumptions made by the Windows implementation:
2773   // 1. The current directory always exists.
2774   // 2. The root directory always exists.
2775   ASSERT_TRUE(DirectoryExists(FilePath(FilePath::kCurrentDirectory)));
2776   FilePath top_level = test_root;
2777   while (top_level != top_level.DirName()) {
2778     top_level = top_level.DirName();
2779   }
2780   ASSERT_TRUE(DirectoryExists(top_level));
2781 
2782   // Given these assumptions hold, it should be safe to
2783   // test that "creating" these directories succeeds.
2784   EXPECT_TRUE(CreateDirectory(
2785       FilePath(FilePath::kCurrentDirectory)));
2786   EXPECT_TRUE(CreateDirectory(top_level));
2787 
2788 #if defined(OS_WIN)
2789   FilePath invalid_drive(FILE_PATH_LITERAL("o:\\"));
2790   FilePath invalid_path =
2791       invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir"));
2792   if (!PathExists(invalid_drive)) {
2793     EXPECT_FALSE(CreateDirectory(invalid_path));
2794   }
2795 #endif
2796 }
2797 
TEST_F(FileUtilTest,DetectDirectoryTest)2798 TEST_F(FileUtilTest, DetectDirectoryTest) {
2799   // Check a directory
2800   FilePath test_root =
2801       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("detect_directory_test"));
2802   EXPECT_FALSE(PathExists(test_root));
2803   EXPECT_TRUE(CreateDirectory(test_root));
2804   EXPECT_TRUE(PathExists(test_root));
2805   EXPECT_TRUE(DirectoryExists(test_root));
2806   // Check a file
2807   FilePath test_path =
2808       test_root.Append(FILE_PATH_LITERAL("foobar.txt"));
2809   EXPECT_FALSE(PathExists(test_path));
2810   CreateTextFile(test_path, L"test file");
2811   EXPECT_TRUE(PathExists(test_path));
2812   EXPECT_FALSE(DirectoryExists(test_path));
2813   EXPECT_TRUE(DeleteFile(test_path, false));
2814 
2815   EXPECT_TRUE(DeleteFileRecursively(test_root));
2816 }
2817 
TEST_F(FileUtilTest,FileEnumeratorTest)2818 TEST_F(FileUtilTest, FileEnumeratorTest) {
2819   // Test an empty directory.
2820   FileEnumerator f0(temp_dir_.GetPath(), true, FILES_AND_DIRECTORIES);
2821   EXPECT_EQ(FPL(""), f0.Next().value());
2822   EXPECT_EQ(FPL(""), f0.Next().value());
2823 
2824   // Test an empty directory, non-recursively, including "..".
2825   FileEnumerator f0_dotdot(
2826       temp_dir_.GetPath(), false,
2827       FILES_AND_DIRECTORIES | FileEnumerator::INCLUDE_DOT_DOT);
2828   EXPECT_EQ(temp_dir_.GetPath().Append(FPL("..")).value(),
2829             f0_dotdot.Next().value());
2830   EXPECT_EQ(FPL(""), f0_dotdot.Next().value());
2831 
2832   // create the directories
2833   FilePath dir1 = temp_dir_.GetPath().Append(FPL("dir1"));
2834   EXPECT_TRUE(CreateDirectory(dir1));
2835   FilePath dir2 = temp_dir_.GetPath().Append(FPL("dir2"));
2836   EXPECT_TRUE(CreateDirectory(dir2));
2837   FilePath dir2inner = dir2.Append(FPL("inner"));
2838   EXPECT_TRUE(CreateDirectory(dir2inner));
2839 
2840   // create the files
2841   FilePath dir2file = dir2.Append(FPL("dir2file.txt"));
2842   CreateTextFile(dir2file, std::wstring());
2843   FilePath dir2innerfile = dir2inner.Append(FPL("innerfile.txt"));
2844   CreateTextFile(dir2innerfile, std::wstring());
2845   FilePath file1 = temp_dir_.GetPath().Append(FPL("file1.txt"));
2846   CreateTextFile(file1, std::wstring());
2847   FilePath file2_rel = dir2.Append(FilePath::kParentDirectory)
2848       .Append(FPL("file2.txt"));
2849   CreateTextFile(file2_rel, std::wstring());
2850   FilePath file2_abs = temp_dir_.GetPath().Append(FPL("file2.txt"));
2851 
2852   // Only enumerate files.
2853   FileEnumerator f1(temp_dir_.GetPath(), true, FileEnumerator::FILES);
2854   FindResultCollector c1(&f1);
2855   EXPECT_TRUE(c1.HasFile(file1));
2856   EXPECT_TRUE(c1.HasFile(file2_abs));
2857   EXPECT_TRUE(c1.HasFile(dir2file));
2858   EXPECT_TRUE(c1.HasFile(dir2innerfile));
2859   EXPECT_EQ(4, c1.size());
2860 
2861   // Only enumerate directories.
2862   FileEnumerator f2(temp_dir_.GetPath(), true, FileEnumerator::DIRECTORIES);
2863   FindResultCollector c2(&f2);
2864   EXPECT_TRUE(c2.HasFile(dir1));
2865   EXPECT_TRUE(c2.HasFile(dir2));
2866   EXPECT_TRUE(c2.HasFile(dir2inner));
2867   EXPECT_EQ(3, c2.size());
2868 
2869   // Only enumerate directories non-recursively.
2870   FileEnumerator f2_non_recursive(temp_dir_.GetPath(), false,
2871                                   FileEnumerator::DIRECTORIES);
2872   FindResultCollector c2_non_recursive(&f2_non_recursive);
2873   EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
2874   EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
2875   EXPECT_EQ(2, c2_non_recursive.size());
2876 
2877   // Only enumerate directories, non-recursively, including "..".
2878   FileEnumerator f2_dotdot(
2879       temp_dir_.GetPath(), false,
2880       FileEnumerator::DIRECTORIES | FileEnumerator::INCLUDE_DOT_DOT);
2881   FindResultCollector c2_dotdot(&f2_dotdot);
2882   EXPECT_TRUE(c2_dotdot.HasFile(dir1));
2883   EXPECT_TRUE(c2_dotdot.HasFile(dir2));
2884   EXPECT_TRUE(c2_dotdot.HasFile(temp_dir_.GetPath().Append(FPL(".."))));
2885   EXPECT_EQ(3, c2_dotdot.size());
2886 
2887   // Enumerate files and directories.
2888   FileEnumerator f3(temp_dir_.GetPath(), true, FILES_AND_DIRECTORIES);
2889   FindResultCollector c3(&f3);
2890   EXPECT_TRUE(c3.HasFile(dir1));
2891   EXPECT_TRUE(c3.HasFile(dir2));
2892   EXPECT_TRUE(c3.HasFile(file1));
2893   EXPECT_TRUE(c3.HasFile(file2_abs));
2894   EXPECT_TRUE(c3.HasFile(dir2file));
2895   EXPECT_TRUE(c3.HasFile(dir2inner));
2896   EXPECT_TRUE(c3.HasFile(dir2innerfile));
2897   EXPECT_EQ(7, c3.size());
2898 
2899   // Non-recursive operation.
2900   FileEnumerator f4(temp_dir_.GetPath(), false, FILES_AND_DIRECTORIES);
2901   FindResultCollector c4(&f4);
2902   EXPECT_TRUE(c4.HasFile(dir2));
2903   EXPECT_TRUE(c4.HasFile(dir2));
2904   EXPECT_TRUE(c4.HasFile(file1));
2905   EXPECT_TRUE(c4.HasFile(file2_abs));
2906   EXPECT_EQ(4, c4.size());
2907 
2908   // Enumerate with a pattern.
2909   FileEnumerator f5(temp_dir_.GetPath(), true, FILES_AND_DIRECTORIES,
2910                     FPL("dir*"));
2911   FindResultCollector c5(&f5);
2912   EXPECT_TRUE(c5.HasFile(dir1));
2913   EXPECT_TRUE(c5.HasFile(dir2));
2914   EXPECT_TRUE(c5.HasFile(dir2file));
2915   EXPECT_TRUE(c5.HasFile(dir2inner));
2916   EXPECT_TRUE(c5.HasFile(dir2innerfile));
2917   EXPECT_EQ(5, c5.size());
2918 
2919 #if defined(OS_WIN)
2920   {
2921     // Make dir1 point to dir2.
2922     ReparsePoint reparse_point(dir1, dir2);
2923     EXPECT_TRUE(reparse_point.IsValid());
2924 
2925     // There can be a delay for the enumeration code to see the change on
2926     // the file system so skip this test for XP.
2927     // Enumerate the reparse point.
2928     FileEnumerator f6(dir1, true, FILES_AND_DIRECTORIES);
2929     FindResultCollector c6(&f6);
2930     FilePath inner2 = dir1.Append(FPL("inner"));
2931     EXPECT_TRUE(c6.HasFile(inner2));
2932     EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt"))));
2933     EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt"))));
2934     EXPECT_EQ(3, c6.size());
2935 
2936     // No changes for non recursive operation.
2937     FileEnumerator f7(temp_dir_.GetPath(), false, FILES_AND_DIRECTORIES);
2938     FindResultCollector c7(&f7);
2939     EXPECT_TRUE(c7.HasFile(dir2));
2940     EXPECT_TRUE(c7.HasFile(dir2));
2941     EXPECT_TRUE(c7.HasFile(file1));
2942     EXPECT_TRUE(c7.HasFile(file2_abs));
2943     EXPECT_EQ(4, c7.size());
2944 
2945     // Should not enumerate inside dir1 when using recursion.
2946     FileEnumerator f8(temp_dir_.GetPath(), true, FILES_AND_DIRECTORIES);
2947     FindResultCollector c8(&f8);
2948     EXPECT_TRUE(c8.HasFile(dir1));
2949     EXPECT_TRUE(c8.HasFile(dir2));
2950     EXPECT_TRUE(c8.HasFile(file1));
2951     EXPECT_TRUE(c8.HasFile(file2_abs));
2952     EXPECT_TRUE(c8.HasFile(dir2file));
2953     EXPECT_TRUE(c8.HasFile(dir2inner));
2954     EXPECT_TRUE(c8.HasFile(dir2innerfile));
2955     EXPECT_EQ(7, c8.size());
2956   }
2957 #endif
2958 
2959   // Make sure the destructor closes the find handle while in the middle of a
2960   // query to allow TearDown to delete the directory.
2961   FileEnumerator f9(temp_dir_.GetPath(), true, FILES_AND_DIRECTORIES);
2962   EXPECT_FALSE(f9.Next().value().empty());  // Should have found something
2963                                             // (we don't care what).
2964 }
2965 
TEST_F(FileUtilTest,AppendToFile)2966 TEST_F(FileUtilTest, AppendToFile) {
2967   FilePath data_dir =
2968       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("FilePathTest"));
2969 
2970   // Create a fresh, empty copy of this directory.
2971   if (PathExists(data_dir)) {
2972     ASSERT_TRUE(DeleteFileRecursively(data_dir));
2973   }
2974   ASSERT_TRUE(CreateDirectory(data_dir));
2975 
2976   // Create a fresh, empty copy of this directory.
2977   if (PathExists(data_dir)) {
2978     ASSERT_TRUE(DeleteFileRecursively(data_dir));
2979   }
2980   ASSERT_TRUE(CreateDirectory(data_dir));
2981   FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
2982 
2983   std::string data("hello");
2984   EXPECT_FALSE(AppendToFile(foobar, data.c_str(), data.size()));
2985   EXPECT_EQ(static_cast<int>(data.length()),
2986             WriteFile(foobar, data.c_str(), data.length()));
2987   EXPECT_TRUE(AppendToFile(foobar, data.c_str(), data.size()));
2988 
2989   const std::wstring read_content = ReadTextFile(foobar);
2990   EXPECT_EQ(L"hellohello", read_content);
2991 }
2992 
TEST_F(FileUtilTest,ReadFile)2993 TEST_F(FileUtilTest, ReadFile) {
2994   // Create a test file to be read.
2995   const std::string kTestData("The quick brown fox jumps over the lazy dog.");
2996   FilePath file_path =
2997       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("ReadFileTest"));
2998 
2999   ASSERT_EQ(static_cast<int>(kTestData.size()),
3000             WriteFile(file_path, kTestData.data(), kTestData.size()));
3001 
3002   // Make buffers with various size.
3003   std::vector<char> small_buffer(kTestData.size() / 2);
3004   std::vector<char> exact_buffer(kTestData.size());
3005   std::vector<char> large_buffer(kTestData.size() * 2);
3006 
3007   // Read the file with smaller buffer.
3008   int bytes_read_small = ReadFile(
3009       file_path, &small_buffer[0], static_cast<int>(small_buffer.size()));
3010   EXPECT_EQ(static_cast<int>(small_buffer.size()), bytes_read_small);
3011   EXPECT_EQ(
3012       std::string(kTestData.begin(), kTestData.begin() + small_buffer.size()),
3013       std::string(small_buffer.begin(), small_buffer.end()));
3014 
3015   // Read the file with buffer which have exactly same size.
3016   int bytes_read_exact = ReadFile(
3017       file_path, &exact_buffer[0], static_cast<int>(exact_buffer.size()));
3018   EXPECT_EQ(static_cast<int>(kTestData.size()), bytes_read_exact);
3019   EXPECT_EQ(kTestData, std::string(exact_buffer.begin(), exact_buffer.end()));
3020 
3021   // Read the file with larger buffer.
3022   int bytes_read_large = ReadFile(
3023       file_path, &large_buffer[0], static_cast<int>(large_buffer.size()));
3024   EXPECT_EQ(static_cast<int>(kTestData.size()), bytes_read_large);
3025   EXPECT_EQ(kTestData, std::string(large_buffer.begin(),
3026                                    large_buffer.begin() + kTestData.size()));
3027 
3028   // Make sure the return value is -1 if the file doesn't exist.
3029   FilePath file_path_not_exist =
3030       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("ReadFileNotExistTest"));
3031   EXPECT_EQ(-1,
3032             ReadFile(file_path_not_exist,
3033                      &exact_buffer[0],
3034                      static_cast<int>(exact_buffer.size())));
3035 }
3036 
TEST_F(FileUtilTest,ReadFileToString)3037 TEST_F(FileUtilTest, ReadFileToString) {
3038   const char kTestData[] = "0123";
3039   std::string data;
3040 
3041   FilePath file_path =
3042       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
3043   FilePath file_path_dangerous =
3044       temp_dir_.GetPath()
3045           .Append(FILE_PATH_LITERAL(".."))
3046           .Append(temp_dir_.GetPath().BaseName())
3047           .Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
3048 
3049   // Create test file.
3050   ASSERT_EQ(static_cast<int>(strlen(kTestData)),
3051             WriteFile(file_path, kTestData, strlen(kTestData)));
3052 
3053   EXPECT_TRUE(ReadFileToString(file_path, &data));
3054   EXPECT_EQ(kTestData, data);
3055 
3056   data = "temp";
3057   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 0));
3058   EXPECT_EQ(0u, data.length());
3059 
3060   data = "temp";
3061   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 2));
3062   EXPECT_EQ("01", data);
3063 
3064   data = "temp";
3065   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 3));
3066   EXPECT_EQ("012", data);
3067 
3068   data = "temp";
3069   EXPECT_TRUE(ReadFileToStringWithMaxSize(file_path, &data, 4));
3070   EXPECT_EQ("0123", data);
3071 
3072   data = "temp";
3073   EXPECT_TRUE(ReadFileToStringWithMaxSize(file_path, &data, 6));
3074   EXPECT_EQ("0123", data);
3075 
3076   EXPECT_TRUE(ReadFileToStringWithMaxSize(file_path, nullptr, 6));
3077 
3078   EXPECT_TRUE(ReadFileToString(file_path, nullptr));
3079 
3080   data = "temp";
3081   EXPECT_FALSE(ReadFileToString(file_path_dangerous, &data));
3082   EXPECT_EQ(0u, data.length());
3083 
3084   // Delete test file.
3085   EXPECT_TRUE(DeleteFile(file_path, false));
3086 
3087   data = "temp";
3088   EXPECT_FALSE(ReadFileToString(file_path, &data));
3089   EXPECT_EQ(0u, data.length());
3090 
3091   data = "temp";
3092   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 6));
3093   EXPECT_EQ(0u, data.length());
3094 }
3095 
3096 #if !defined(OS_WIN)
TEST_F(FileUtilTest,ReadFileToStringWithUnknownFileSize)3097 TEST_F(FileUtilTest, ReadFileToStringWithUnknownFileSize) {
3098   FilePath file_path("/dev/zero");
3099   std::string data = "temp";
3100 
3101   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 0));
3102   EXPECT_EQ(0u, data.length());
3103 
3104   data = "temp";
3105   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 2));
3106   EXPECT_EQ(std::string(2, '\0'), data);
3107 
3108   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, nullptr, 6));
3109 
3110   // Read more than buffer size.
3111   data = "temp";
3112   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, kLargeFileSize));
3113   EXPECT_EQ(kLargeFileSize, data.length());
3114   EXPECT_EQ(std::string(kLargeFileSize, '\0'), data);
3115 
3116   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, nullptr, kLargeFileSize));
3117 }
3118 #endif  // !defined(OS_WIN)
3119 
3120 #if !defined(OS_WIN) && !defined(OS_NACL) && !defined(OS_FUCHSIA) && \
3121     !defined(OS_IOS)
3122 #define ChildMain WriteToPipeChildMain
3123 #define ChildMainString "WriteToPipeChildMain"
3124 
MULTIPROCESS_TEST_MAIN(ChildMain)3125 MULTIPROCESS_TEST_MAIN(ChildMain) {
3126   const char kTestData[] = "0123";
3127   CommandLine* command_line = CommandLine::ForCurrentProcess();
3128   const FilePath pipe_path = command_line->GetSwitchValuePath("pipe-path");
3129 
3130   int fd = open(pipe_path.value().c_str(), O_WRONLY);
3131   CHECK_NE(-1, fd);
3132   size_t written = 0;
3133   while (written < strlen(kTestData)) {
3134     ssize_t res = write(fd, kTestData + written, strlen(kTestData) - written);
3135     if (res == -1)
3136       break;
3137     written += res;
3138   }
3139   CHECK_EQ(strlen(kTestData), written);
3140   CHECK_EQ(0, close(fd));
3141   return 0;
3142 }
3143 
3144 #define MoreThanBufferSizeChildMain WriteToPipeMoreThanBufferSizeChildMain
3145 #define MoreThanBufferSizeChildMainString \
3146   "WriteToPipeMoreThanBufferSizeChildMain"
3147 
MULTIPROCESS_TEST_MAIN(MoreThanBufferSizeChildMain)3148 MULTIPROCESS_TEST_MAIN(MoreThanBufferSizeChildMain) {
3149   std::string data(kLargeFileSize, 'c');
3150   CommandLine* command_line = CommandLine::ForCurrentProcess();
3151   const FilePath pipe_path = command_line->GetSwitchValuePath("pipe-path");
3152 
3153   int fd = open(pipe_path.value().c_str(), O_WRONLY);
3154   CHECK_NE(-1, fd);
3155 
3156   size_t written = 0;
3157   while (written < data.size()) {
3158     ssize_t res = write(fd, data.c_str() + written, data.size() - written);
3159     if (res == -1) {
3160       // We are unable to write because reading process has already read
3161       // requested number of bytes and closed pipe.
3162       break;
3163     }
3164     written += res;
3165   }
3166   CHECK_EQ(0, close(fd));
3167   return 0;
3168 }
3169 
TEST_F(FileUtilTest,ReadFileToStringWithNamedPipe)3170 TEST_F(FileUtilTest, ReadFileToStringWithNamedPipe) {
3171   FilePath pipe_path =
3172       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("test_pipe"));
3173   ASSERT_EQ(0, mkfifo(pipe_path.value().c_str(), 0600));
3174 
3175   CommandLine child_command_line(GetMultiProcessTestChildBaseCommandLine());
3176   child_command_line.AppendSwitchPath("pipe-path", pipe_path);
3177 
3178   {
3179     Process child_process = SpawnMultiProcessTestChild(
3180         ChildMainString, child_command_line, LaunchOptions());
3181     ASSERT_TRUE(child_process.IsValid());
3182 
3183     std::string data = "temp";
3184     EXPECT_FALSE(ReadFileToStringWithMaxSize(pipe_path, &data, 2));
3185     EXPECT_EQ("01", data);
3186 
3187     int rv = -1;
3188     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3189         child_process, TestTimeouts::action_timeout(), &rv));
3190     ASSERT_EQ(0, rv);
3191   }
3192   {
3193     Process child_process = SpawnMultiProcessTestChild(
3194         ChildMainString, child_command_line, LaunchOptions());
3195     ASSERT_TRUE(child_process.IsValid());
3196 
3197     std::string data = "temp";
3198     EXPECT_TRUE(ReadFileToStringWithMaxSize(pipe_path, &data, 6));
3199     EXPECT_EQ("0123", data);
3200 
3201     int rv = -1;
3202     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3203         child_process, TestTimeouts::action_timeout(), &rv));
3204     ASSERT_EQ(0, rv);
3205   }
3206   {
3207     Process child_process = SpawnMultiProcessTestChild(
3208         MoreThanBufferSizeChildMainString, child_command_line, LaunchOptions());
3209     ASSERT_TRUE(child_process.IsValid());
3210 
3211     std::string data = "temp";
3212     EXPECT_FALSE(ReadFileToStringWithMaxSize(pipe_path, &data, 6));
3213     EXPECT_EQ("cccccc", data);
3214 
3215     int rv = -1;
3216     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3217         child_process, TestTimeouts::action_timeout(), &rv));
3218     ASSERT_EQ(0, rv);
3219   }
3220   {
3221     Process child_process = SpawnMultiProcessTestChild(
3222         MoreThanBufferSizeChildMainString, child_command_line, LaunchOptions());
3223     ASSERT_TRUE(child_process.IsValid());
3224 
3225     std::string data = "temp";
3226     EXPECT_FALSE(
3227         ReadFileToStringWithMaxSize(pipe_path, &data, kLargeFileSize - 1));
3228     EXPECT_EQ(std::string(kLargeFileSize - 1, 'c'), data);
3229 
3230     int rv = -1;
3231     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3232         child_process, TestTimeouts::action_timeout(), &rv));
3233     ASSERT_EQ(0, rv);
3234   }
3235   {
3236     Process child_process = SpawnMultiProcessTestChild(
3237         MoreThanBufferSizeChildMainString, child_command_line, LaunchOptions());
3238     ASSERT_TRUE(child_process.IsValid());
3239 
3240     std::string data = "temp";
3241     EXPECT_TRUE(ReadFileToStringWithMaxSize(pipe_path, &data, kLargeFileSize));
3242     EXPECT_EQ(std::string(kLargeFileSize, 'c'), data);
3243 
3244     int rv = -1;
3245     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3246         child_process, TestTimeouts::action_timeout(), &rv));
3247     ASSERT_EQ(0, rv);
3248   }
3249   {
3250     Process child_process = SpawnMultiProcessTestChild(
3251         MoreThanBufferSizeChildMainString, child_command_line, LaunchOptions());
3252     ASSERT_TRUE(child_process.IsValid());
3253 
3254     std::string data = "temp";
3255     EXPECT_TRUE(
3256         ReadFileToStringWithMaxSize(pipe_path, &data, kLargeFileSize * 5));
3257     EXPECT_EQ(std::string(kLargeFileSize, 'c'), data);
3258 
3259     int rv = -1;
3260     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3261         child_process, TestTimeouts::action_timeout(), &rv));
3262     ASSERT_EQ(0, rv);
3263   }
3264 
3265   ASSERT_EQ(0, unlink(pipe_path.value().c_str()));
3266 }
3267 #endif  // !defined(OS_WIN) && !defined(OS_NACL) && !defined(OS_FUCHSIA) &&
3268         // !defined(OS_IOS)
3269 
3270 #if defined(OS_WIN)
3271 #define ChildMain WriteToPipeChildMain
3272 #define ChildMainString "WriteToPipeChildMain"
3273 
MULTIPROCESS_TEST_MAIN(ChildMain)3274 MULTIPROCESS_TEST_MAIN(ChildMain) {
3275   const char kTestData[] = "0123";
3276   CommandLine* command_line = CommandLine::ForCurrentProcess();
3277   const FilePath pipe_path = command_line->GetSwitchValuePath("pipe-path");
3278   std::string switch_string = command_line->GetSwitchValueASCII("sync_event");
3279   EXPECT_FALSE(switch_string.empty());
3280   unsigned int switch_uint = 0;
3281   EXPECT_TRUE(StringToUint(switch_string, &switch_uint));
3282   win::ScopedHandle sync_event(win::Uint32ToHandle(switch_uint));
3283 
3284   HANDLE ph = CreateNamedPipe(pipe_path.value().c_str(), PIPE_ACCESS_OUTBOUND,
3285                               PIPE_WAIT, 1, 0, 0, 0, NULL);
3286   EXPECT_NE(ph, INVALID_HANDLE_VALUE);
3287   EXPECT_TRUE(SetEvent(sync_event.Get()));
3288   EXPECT_TRUE(ConnectNamedPipe(ph, NULL));
3289 
3290   DWORD written;
3291   EXPECT_TRUE(::WriteFile(ph, kTestData, strlen(kTestData), &written, NULL));
3292   EXPECT_EQ(strlen(kTestData), written);
3293   CloseHandle(ph);
3294   return 0;
3295 }
3296 
3297 #define MoreThanBufferSizeChildMain WriteToPipeMoreThanBufferSizeChildMain
3298 #define MoreThanBufferSizeChildMainString \
3299   "WriteToPipeMoreThanBufferSizeChildMain"
3300 
MULTIPROCESS_TEST_MAIN(MoreThanBufferSizeChildMain)3301 MULTIPROCESS_TEST_MAIN(MoreThanBufferSizeChildMain) {
3302   std::string data(kLargeFileSize, 'c');
3303   CommandLine* command_line = CommandLine::ForCurrentProcess();
3304   const FilePath pipe_path = command_line->GetSwitchValuePath("pipe-path");
3305   std::string switch_string = command_line->GetSwitchValueASCII("sync_event");
3306   EXPECT_FALSE(switch_string.empty());
3307   unsigned int switch_uint = 0;
3308   EXPECT_TRUE(StringToUint(switch_string, &switch_uint));
3309   win::ScopedHandle sync_event(win::Uint32ToHandle(switch_uint));
3310 
3311   HANDLE ph = CreateNamedPipe(pipe_path.value().c_str(), PIPE_ACCESS_OUTBOUND,
3312                               PIPE_WAIT, 1, data.size(), data.size(), 0, NULL);
3313   EXPECT_NE(ph, INVALID_HANDLE_VALUE);
3314   EXPECT_TRUE(SetEvent(sync_event.Get()));
3315   EXPECT_TRUE(ConnectNamedPipe(ph, NULL));
3316 
3317   DWORD written;
3318   EXPECT_TRUE(::WriteFile(ph, data.c_str(), data.size(), &written, NULL));
3319   EXPECT_EQ(data.size(), written);
3320   CloseHandle(ph);
3321   return 0;
3322 }
3323 
TEST_F(FileUtilTest,ReadFileToStringWithNamedPipe)3324 TEST_F(FileUtilTest, ReadFileToStringWithNamedPipe) {
3325   FilePath pipe_path(FILE_PATH_LITERAL("\\\\.\\pipe\\test_pipe"));
3326   win::ScopedHandle sync_event(CreateEvent(0, false, false, nullptr));
3327 
3328   CommandLine child_command_line(GetMultiProcessTestChildBaseCommandLine());
3329   child_command_line.AppendSwitchPath("pipe-path", pipe_path);
3330   child_command_line.AppendSwitchASCII(
3331       "sync_event", NumberToString(win::HandleToUint32(sync_event.Get())));
3332 
3333   LaunchOptions options;
3334   options.handles_to_inherit.push_back(sync_event.Get());
3335 
3336   {
3337     Process child_process = SpawnMultiProcessTestChild(
3338         ChildMainString, child_command_line, options);
3339     ASSERT_TRUE(child_process.IsValid());
3340     // Wait for pipe creation in child process.
3341     EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(sync_event.Get(), INFINITE));
3342 
3343     std::string data = "temp";
3344     EXPECT_FALSE(ReadFileToStringWithMaxSize(pipe_path, &data, 2));
3345     EXPECT_EQ("01", data);
3346 
3347     int rv = -1;
3348     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3349         child_process, TestTimeouts::action_timeout(), &rv));
3350     ASSERT_EQ(0, rv);
3351   }
3352   {
3353     Process child_process = SpawnMultiProcessTestChild(
3354         ChildMainString, child_command_line, options);
3355     ASSERT_TRUE(child_process.IsValid());
3356     // Wait for pipe creation in child process.
3357     EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(sync_event.Get(), INFINITE));
3358 
3359     std::string data = "temp";
3360     EXPECT_TRUE(ReadFileToStringWithMaxSize(pipe_path, &data, 6));
3361     EXPECT_EQ("0123", data);
3362 
3363     int rv = -1;
3364     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3365         child_process, TestTimeouts::action_timeout(), &rv));
3366     ASSERT_EQ(0, rv);
3367   }
3368   {
3369     Process child_process = SpawnMultiProcessTestChild(
3370         MoreThanBufferSizeChildMainString, child_command_line, options);
3371     ASSERT_TRUE(child_process.IsValid());
3372     // Wait for pipe creation in child process.
3373     EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(sync_event.Get(), INFINITE));
3374 
3375     std::string data = "temp";
3376     EXPECT_FALSE(ReadFileToStringWithMaxSize(pipe_path, &data, 6));
3377     EXPECT_EQ("cccccc", data);
3378 
3379     int rv = -1;
3380     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3381         child_process, TestTimeouts::action_timeout(), &rv));
3382     ASSERT_EQ(0, rv);
3383   }
3384   {
3385     Process child_process = SpawnMultiProcessTestChild(
3386         MoreThanBufferSizeChildMainString, child_command_line, options);
3387     ASSERT_TRUE(child_process.IsValid());
3388     // Wait for pipe creation in child process.
3389     EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(sync_event.Get(), INFINITE));
3390 
3391     std::string data = "temp";
3392     EXPECT_FALSE(
3393         ReadFileToStringWithMaxSize(pipe_path, &data, kLargeFileSize - 1));
3394     EXPECT_EQ(std::string(kLargeFileSize - 1, 'c'), data);
3395 
3396     int rv = -1;
3397     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3398         child_process, TestTimeouts::action_timeout(), &rv));
3399     ASSERT_EQ(0, rv);
3400   }
3401   {
3402     Process child_process = SpawnMultiProcessTestChild(
3403         MoreThanBufferSizeChildMainString, child_command_line, options);
3404     ASSERT_TRUE(child_process.IsValid());
3405     // Wait for pipe creation in child process.
3406     EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(sync_event.Get(), INFINITE));
3407 
3408     std::string data = "temp";
3409     EXPECT_TRUE(ReadFileToStringWithMaxSize(pipe_path, &data, kLargeFileSize));
3410     EXPECT_EQ(std::string(kLargeFileSize, 'c'), data);
3411 
3412     int rv = -1;
3413     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3414         child_process, TestTimeouts::action_timeout(), &rv));
3415     ASSERT_EQ(0, rv);
3416   }
3417   {
3418     Process child_process = SpawnMultiProcessTestChild(
3419         MoreThanBufferSizeChildMainString, child_command_line, options);
3420     ASSERT_TRUE(child_process.IsValid());
3421     // Wait for pipe creation in child process.
3422     EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(sync_event.Get(), INFINITE));
3423 
3424     std::string data = "temp";
3425     EXPECT_TRUE(
3426         ReadFileToStringWithMaxSize(pipe_path, &data, kLargeFileSize * 5));
3427     EXPECT_EQ(std::string(kLargeFileSize, 'c'), data);
3428 
3429     int rv = -1;
3430     ASSERT_TRUE(WaitForMultiprocessTestChildExit(
3431         child_process, TestTimeouts::action_timeout(), &rv));
3432     ASSERT_EQ(0, rv);
3433   }
3434 }
3435 #endif  // defined(OS_WIN)
3436 
3437 #if defined(OS_POSIX) && !defined(OS_MACOSX)
TEST_F(FileUtilTest,ReadFileToStringWithProcFileSystem)3438 TEST_F(FileUtilTest, ReadFileToStringWithProcFileSystem) {
3439   FilePath file_path("/proc/cpuinfo");
3440   std::string data = "temp";
3441 
3442   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 0));
3443   EXPECT_EQ(0u, data.length());
3444 
3445   data = "temp";
3446   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 2));
3447   EXPECT_TRUE(EqualsCaseInsensitiveASCII("pr", data));
3448 
3449   data = "temp";
3450   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 4));
3451   EXPECT_TRUE(EqualsCaseInsensitiveASCII("proc", data));
3452 
3453   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, nullptr, 4));
3454 }
3455 #endif  // defined(OS_POSIX) && !defined(OS_MACOSX)
3456 
TEST_F(FileUtilTest,ReadFileToStringWithLargeFile)3457 TEST_F(FileUtilTest, ReadFileToStringWithLargeFile) {
3458   std::string data(kLargeFileSize, 'c');
3459 
3460   FilePath file_path =
3461       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
3462 
3463   // Create test file.
3464   ASSERT_EQ(static_cast<int>(kLargeFileSize),
3465             WriteFile(file_path, data.c_str(), kLargeFileSize));
3466 
3467   std::string actual_data = "temp";
3468   EXPECT_TRUE(ReadFileToString(file_path, &actual_data));
3469   EXPECT_EQ(data, actual_data);
3470 
3471   actual_data = "temp";
3472   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &actual_data, 0));
3473   EXPECT_EQ(0u, actual_data.length());
3474 
3475   // Read more than buffer size.
3476   actual_data = "temp";
3477   EXPECT_FALSE(
3478       ReadFileToStringWithMaxSize(file_path, &actual_data, kLargeFileSize - 1));
3479   EXPECT_EQ(std::string(kLargeFileSize - 1, 'c'), actual_data);
3480 }
3481 
TEST_F(FileUtilTest,TouchFile)3482 TEST_F(FileUtilTest, TouchFile) {
3483   FilePath data_dir =
3484       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("FilePathTest"));
3485 
3486   // Create a fresh, empty copy of this directory.
3487   if (PathExists(data_dir)) {
3488     ASSERT_TRUE(DeleteFileRecursively(data_dir));
3489   }
3490   ASSERT_TRUE(CreateDirectory(data_dir));
3491 
3492   FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
3493   std::string data("hello");
3494   ASSERT_EQ(static_cast<int>(data.length()),
3495             WriteFile(foobar, data.c_str(), data.length()));
3496 
3497   Time access_time;
3498   // This timestamp is divisible by one day (in local timezone),
3499   // to make it work on FAT too.
3500   ASSERT_TRUE(Time::FromString("Wed, 16 Nov 1994, 00:00:00",
3501                                &access_time));
3502 
3503   Time modification_time;
3504   // Note that this timestamp is divisible by two (seconds) - FAT stores
3505   // modification times with 2s resolution.
3506   ASSERT_TRUE(Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT",
3507               &modification_time));
3508 
3509   ASSERT_TRUE(TouchFile(foobar, access_time, modification_time));
3510   File::Info file_info;
3511   ASSERT_TRUE(GetFileInfo(foobar, &file_info));
3512 #if !defined(OS_FUCHSIA)
3513   // Access time is not supported on Fuchsia, see https://crbug.com/735233.
3514   EXPECT_EQ(access_time.ToInternalValue(),
3515             file_info.last_accessed.ToInternalValue());
3516 #endif
3517   EXPECT_EQ(modification_time.ToInternalValue(),
3518             file_info.last_modified.ToInternalValue());
3519 }
3520 
TEST_F(FileUtilTest,IsDirectoryEmpty)3521 TEST_F(FileUtilTest, IsDirectoryEmpty) {
3522   FilePath empty_dir =
3523       temp_dir_.GetPath().Append(FILE_PATH_LITERAL("EmptyDir"));
3524 
3525   ASSERT_FALSE(PathExists(empty_dir));
3526 
3527   ASSERT_TRUE(CreateDirectory(empty_dir));
3528 
3529   EXPECT_TRUE(IsDirectoryEmpty(empty_dir));
3530 
3531   FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt")));
3532   std::string bar("baz");
3533   ASSERT_EQ(static_cast<int>(bar.length()),
3534             WriteFile(foo, bar.c_str(), bar.length()));
3535 
3536   EXPECT_FALSE(IsDirectoryEmpty(empty_dir));
3537 }
3538 
3539 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
3540 
TEST_F(FileUtilTest,SetNonBlocking)3541 TEST_F(FileUtilTest, SetNonBlocking) {
3542   const int kBogusFd = 99999;
3543   EXPECT_FALSE(SetNonBlocking(kBogusFd));
3544 
3545   FilePath path;
3546   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &path));
3547   path = path.Append(FPL("file_util")).Append(FPL("original.txt"));
3548   ScopedFD fd(open(path.value().c_str(), O_RDONLY));
3549   ASSERT_GE(fd.get(), 0);
3550   EXPECT_TRUE(SetNonBlocking(fd.get()));
3551 }
3552 
TEST_F(FileUtilTest,SetCloseOnExec)3553 TEST_F(FileUtilTest, SetCloseOnExec) {
3554   const int kBogusFd = 99999;
3555   EXPECT_FALSE(SetCloseOnExec(kBogusFd));
3556 
3557   FilePath path;
3558   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &path));
3559   path = path.Append(FPL("file_util")).Append(FPL("original.txt"));
3560   ScopedFD fd(open(path.value().c_str(), O_RDONLY));
3561   ASSERT_GE(fd.get(), 0);
3562   EXPECT_TRUE(SetCloseOnExec(fd.get()));
3563 }
3564 
3565 #endif
3566 
3567 #if defined(OS_POSIX)
3568 
3569 // Testing VerifyPathControlledByAdmin() is hard, because there is no
3570 // way a test can make a file owned by root, or change file paths
3571 // at the root of the file system.  VerifyPathControlledByAdmin()
3572 // is implemented as a call to VerifyPathControlledByUser, which gives
3573 // us the ability to test with paths under the test's temp directory,
3574 // using a user id we control.
3575 // Pull tests of VerifyPathControlledByUserTest() into a separate test class
3576 // with a common SetUp() method.
3577 class VerifyPathControlledByUserTest : public FileUtilTest {
3578  protected:
SetUp()3579   void SetUp() override {
3580     FileUtilTest::SetUp();
3581 
3582     // Create a basic structure used by each test.
3583     // base_dir_
3584     //  |-> sub_dir_
3585     //       |-> text_file_
3586 
3587     base_dir_ = temp_dir_.GetPath().AppendASCII("base_dir");
3588     ASSERT_TRUE(CreateDirectory(base_dir_));
3589 
3590     sub_dir_ = base_dir_.AppendASCII("sub_dir");
3591     ASSERT_TRUE(CreateDirectory(sub_dir_));
3592 
3593     text_file_ = sub_dir_.AppendASCII("file.txt");
3594     CreateTextFile(text_file_, L"This text file has some text in it.");
3595 
3596     // Get the user and group files are created with from |base_dir_|.
3597     stat_wrapper_t stat_buf;
3598     ASSERT_EQ(0, File::Stat(base_dir_.value().c_str(), &stat_buf));
3599     uid_ = stat_buf.st_uid;
3600     ok_gids_.insert(stat_buf.st_gid);
3601     bad_gids_.insert(stat_buf.st_gid + 1);
3602 
3603     ASSERT_EQ(uid_, getuid());  // This process should be the owner.
3604 
3605     // To ensure that umask settings do not cause the initial state
3606     // of permissions to be different from what we expect, explicitly
3607     // set permissions on the directories we create.
3608     // Make all files and directories non-world-writable.
3609 
3610     // Users and group can read, write, traverse
3611     int enabled_permissions =
3612         FILE_PERMISSION_USER_MASK | FILE_PERMISSION_GROUP_MASK;
3613     // Other users can't read, write, traverse
3614     int disabled_permissions = FILE_PERMISSION_OTHERS_MASK;
3615 
3616     ASSERT_NO_FATAL_FAILURE(
3617         ChangePosixFilePermissions(
3618             base_dir_, enabled_permissions, disabled_permissions));
3619     ASSERT_NO_FATAL_FAILURE(
3620         ChangePosixFilePermissions(
3621             sub_dir_, enabled_permissions, disabled_permissions));
3622   }
3623 
3624   FilePath base_dir_;
3625   FilePath sub_dir_;
3626   FilePath text_file_;
3627   uid_t uid_;
3628 
3629   std::set<gid_t> ok_gids_;
3630   std::set<gid_t> bad_gids_;
3631 };
3632 
TEST_F(VerifyPathControlledByUserTest,BadPaths)3633 TEST_F(VerifyPathControlledByUserTest, BadPaths) {
3634   // File does not exist.
3635   FilePath does_not_exist = base_dir_.AppendASCII("does")
3636                                      .AppendASCII("not")
3637                                      .AppendASCII("exist");
3638   EXPECT_FALSE(
3639       VerifyPathControlledByUser(base_dir_, does_not_exist, uid_, ok_gids_));
3640 
3641   // |base| not a subpath of |path|.
3642   EXPECT_FALSE(VerifyPathControlledByUser(sub_dir_, base_dir_, uid_, ok_gids_));
3643 
3644   // An empty base path will fail to be a prefix for any path.
3645   FilePath empty;
3646   EXPECT_FALSE(VerifyPathControlledByUser(empty, base_dir_, uid_, ok_gids_));
3647 
3648   // Finding that a bad call fails proves nothing unless a good call succeeds.
3649   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3650 }
3651 
TEST_F(VerifyPathControlledByUserTest,Symlinks)3652 TEST_F(VerifyPathControlledByUserTest, Symlinks) {
3653   // Symlinks in the path should cause failure.
3654 
3655   // Symlink to the file at the end of the path.
3656   FilePath file_link =  base_dir_.AppendASCII("file_link");
3657   ASSERT_TRUE(CreateSymbolicLink(text_file_, file_link))
3658       << "Failed to create symlink.";
3659 
3660   EXPECT_FALSE(
3661       VerifyPathControlledByUser(base_dir_, file_link, uid_, ok_gids_));
3662   EXPECT_FALSE(
3663       VerifyPathControlledByUser(file_link, file_link, uid_, ok_gids_));
3664 
3665   // Symlink from one directory to another within the path.
3666   FilePath link_to_sub_dir =  base_dir_.AppendASCII("link_to_sub_dir");
3667   ASSERT_TRUE(CreateSymbolicLink(sub_dir_, link_to_sub_dir))
3668     << "Failed to create symlink.";
3669 
3670   FilePath file_path_with_link = link_to_sub_dir.AppendASCII("file.txt");
3671   ASSERT_TRUE(PathExists(file_path_with_link));
3672 
3673   EXPECT_FALSE(VerifyPathControlledByUser(base_dir_, file_path_with_link, uid_,
3674                                           ok_gids_));
3675 
3676   EXPECT_FALSE(VerifyPathControlledByUser(link_to_sub_dir, file_path_with_link,
3677                                           uid_, ok_gids_));
3678 
3679   // Symlinks in parents of base path are allowed.
3680   EXPECT_TRUE(VerifyPathControlledByUser(file_path_with_link,
3681                                          file_path_with_link, uid_, ok_gids_));
3682 }
3683 
TEST_F(VerifyPathControlledByUserTest,OwnershipChecks)3684 TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) {
3685   // Get a uid that is not the uid of files we create.
3686   uid_t bad_uid = uid_ + 1;
3687 
3688   // Make all files and directories non-world-writable.
3689   ASSERT_NO_FATAL_FAILURE(
3690       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
3691   ASSERT_NO_FATAL_FAILURE(
3692       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
3693   ASSERT_NO_FATAL_FAILURE(
3694       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
3695 
3696   // We control these paths.
3697   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3698   EXPECT_TRUE(
3699       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3700   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3701 
3702   // Another user does not control these paths.
3703   EXPECT_FALSE(
3704       VerifyPathControlledByUser(base_dir_, sub_dir_, bad_uid, ok_gids_));
3705   EXPECT_FALSE(
3706       VerifyPathControlledByUser(base_dir_, text_file_, bad_uid, ok_gids_));
3707   EXPECT_FALSE(
3708       VerifyPathControlledByUser(sub_dir_, text_file_, bad_uid, ok_gids_));
3709 
3710   // Another group does not control the paths.
3711   EXPECT_FALSE(
3712       VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, bad_gids_));
3713   EXPECT_FALSE(
3714       VerifyPathControlledByUser(base_dir_, text_file_, uid_, bad_gids_));
3715   EXPECT_FALSE(
3716       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, bad_gids_));
3717 }
3718 
TEST_F(VerifyPathControlledByUserTest,GroupWriteTest)3719 TEST_F(VerifyPathControlledByUserTest, GroupWriteTest) {
3720   // Make all files and directories writable only by their owner.
3721   ASSERT_NO_FATAL_FAILURE(
3722       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH|S_IWGRP));
3723   ASSERT_NO_FATAL_FAILURE(
3724       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH|S_IWGRP));
3725   ASSERT_NO_FATAL_FAILURE(
3726       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH|S_IWGRP));
3727 
3728   // Any group is okay because the path is not group-writable.
3729   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3730   EXPECT_TRUE(
3731       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3732   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3733 
3734   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, bad_gids_));
3735   EXPECT_TRUE(
3736       VerifyPathControlledByUser(base_dir_, text_file_, uid_, bad_gids_));
3737   EXPECT_TRUE(
3738       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, bad_gids_));
3739 
3740   // No group is okay, because we don't check the group
3741   // if no group can write.
3742   std::set<gid_t> no_gids;  // Empty set of gids.
3743   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, no_gids));
3744   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, text_file_, uid_, no_gids));
3745   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, no_gids));
3746 
3747   // Make all files and directories writable by their group.
3748   ASSERT_NO_FATAL_FAILURE(ChangePosixFilePermissions(base_dir_, S_IWGRP, 0u));
3749   ASSERT_NO_FATAL_FAILURE(ChangePosixFilePermissions(sub_dir_, S_IWGRP, 0u));
3750   ASSERT_NO_FATAL_FAILURE(ChangePosixFilePermissions(text_file_, S_IWGRP, 0u));
3751 
3752   // Now |ok_gids_| works, but |bad_gids_| fails.
3753   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3754   EXPECT_TRUE(
3755       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3756   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3757 
3758   EXPECT_FALSE(
3759       VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, bad_gids_));
3760   EXPECT_FALSE(
3761       VerifyPathControlledByUser(base_dir_, text_file_, uid_, bad_gids_));
3762   EXPECT_FALSE(
3763       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, bad_gids_));
3764 
3765   // Because any group in the group set is allowed,
3766   // the union of good and bad gids passes.
3767 
3768   std::set<gid_t> multiple_gids;
3769   std::set_union(
3770       ok_gids_.begin(), ok_gids_.end(),
3771       bad_gids_.begin(), bad_gids_.end(),
3772       std::inserter(multiple_gids, multiple_gids.begin()));
3773 
3774   EXPECT_TRUE(
3775       VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, multiple_gids));
3776   EXPECT_TRUE(
3777       VerifyPathControlledByUser(base_dir_, text_file_, uid_, multiple_gids));
3778   EXPECT_TRUE(
3779       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, multiple_gids));
3780 }
3781 
TEST_F(VerifyPathControlledByUserTest,WriteBitChecks)3782 TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) {
3783   // Make all files and directories non-world-writable.
3784   ASSERT_NO_FATAL_FAILURE(
3785       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
3786   ASSERT_NO_FATAL_FAILURE(
3787       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
3788   ASSERT_NO_FATAL_FAILURE(
3789       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
3790 
3791   // Initialy, we control all parts of the path.
3792   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3793   EXPECT_TRUE(
3794       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3795   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3796 
3797   // Make base_dir_ world-writable.
3798   ASSERT_NO_FATAL_FAILURE(
3799       ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u));
3800   EXPECT_FALSE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3801   EXPECT_FALSE(
3802       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3803   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3804 
3805   // Make sub_dir_ world writable.
3806   ASSERT_NO_FATAL_FAILURE(
3807       ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u));
3808   EXPECT_FALSE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3809   EXPECT_FALSE(
3810       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3811   EXPECT_FALSE(
3812       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3813 
3814   // Make text_file_ world writable.
3815   ASSERT_NO_FATAL_FAILURE(
3816       ChangePosixFilePermissions(text_file_, S_IWOTH, 0u));
3817   EXPECT_FALSE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3818   EXPECT_FALSE(
3819       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3820   EXPECT_FALSE(
3821       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3822 
3823   // Make sub_dir_ non-world writable.
3824   ASSERT_NO_FATAL_FAILURE(
3825       ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
3826   EXPECT_FALSE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3827   EXPECT_FALSE(
3828       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3829   EXPECT_FALSE(
3830       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3831 
3832   // Make base_dir_ non-world-writable.
3833   ASSERT_NO_FATAL_FAILURE(
3834       ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
3835   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3836   EXPECT_FALSE(
3837       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3838   EXPECT_FALSE(
3839       VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3840 
3841   // Back to the initial state: Nothing is writable, so every path
3842   // should pass.
3843   ASSERT_NO_FATAL_FAILURE(
3844       ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
3845   EXPECT_TRUE(VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, ok_gids_));
3846   EXPECT_TRUE(
3847       VerifyPathControlledByUser(base_dir_, text_file_, uid_, ok_gids_));
3848   EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_));
3849 }
3850 
3851 #endif  // defined(OS_POSIX)
3852 
3853 // Flaky test: crbug/1054637
3854 #if defined(OS_ANDROID)
TEST_F(FileUtilTest,DISABLED_ValidContentUriTest)3855 TEST_F(FileUtilTest, DISABLED_ValidContentUriTest) {
3856   // Get the test image path.
3857   FilePath data_dir;
3858   ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
3859   data_dir = data_dir.AppendASCII("file_util");
3860   ASSERT_TRUE(PathExists(data_dir));
3861   FilePath image_file = data_dir.Append(FILE_PATH_LITERAL("red.png"));
3862   int64_t image_size;
3863   GetFileSize(image_file, &image_size);
3864   ASSERT_GT(image_size, 0);
3865 
3866   // Insert the image into MediaStore. MediaStore will do some conversions, and
3867   // return the content URI.
3868   FilePath path = InsertImageIntoMediaStore(image_file);
3869   EXPECT_TRUE(path.IsContentUri());
3870   EXPECT_TRUE(PathExists(path));
3871   // The file size may not equal to the input image as MediaStore may convert
3872   // the image.
3873   int64_t content_uri_size;
3874   GetFileSize(path, &content_uri_size);
3875   EXPECT_EQ(image_size, content_uri_size);
3876 
3877   // We should be able to read the file.
3878   File file = OpenContentUriForRead(path);
3879   EXPECT_TRUE(file.IsValid());
3880   auto buffer = std::make_unique<char[]>(image_size);
3881   EXPECT_TRUE(file.ReadAtCurrentPos(buffer.get(), image_size));
3882 }
3883 
TEST_F(FileUtilTest,NonExistentContentUriTest)3884 TEST_F(FileUtilTest, NonExistentContentUriTest) {
3885   FilePath path("content://foo.bar");
3886   EXPECT_TRUE(path.IsContentUri());
3887   EXPECT_FALSE(PathExists(path));
3888   // Size should be smaller than 0.
3889   int64_t size;
3890   EXPECT_FALSE(GetFileSize(path, &size));
3891 
3892   // We should not be able to read the file.
3893   File file = OpenContentUriForRead(path);
3894   EXPECT_FALSE(file.IsValid());
3895 }
3896 #endif
3897 
3898 #if !defined(OS_NACL_NONSFI)
TEST_F(FileUtilTest,GetUniquePathNumberNoFile)3899 TEST_F(FileUtilTest, GetUniquePathNumberNoFile) {
3900   // This file does not exist.
3901   const FilePath some_file = temp_dir_.GetPath().Append(FPL("SomeFile.txt"));
3902 
3903   // The path is unique as-is.
3904   EXPECT_EQ(GetUniquePathNumber(some_file), 0);
3905 }
3906 
TEST_F(FileUtilTest,GetUniquePathNumberFileExists)3907 TEST_F(FileUtilTest, GetUniquePathNumberFileExists) {
3908   // Create a file with the desired path.
3909   const FilePath some_file = temp_dir_.GetPath().Append(FPL("SomeFile.txt"));
3910   ASSERT_TRUE(File(some_file, File::FLAG_CREATE | File::FLAG_WRITE).IsValid());
3911 
3912   // The file exists, so the number 1 is needed to make it unique.
3913   EXPECT_EQ(GetUniquePathNumber(some_file), 1);
3914 }
3915 
TEST_F(FileUtilTest,GetUniquePathNumberFilesExist)3916 TEST_F(FileUtilTest, GetUniquePathNumberFilesExist) {
3917   // Create a file with the desired path and with it suffixed with " (1)"
3918   const FilePath some_file = temp_dir_.GetPath().Append(FPL("SomeFile.txt"));
3919   ASSERT_TRUE(File(some_file, File::FLAG_CREATE | File::FLAG_WRITE).IsValid());
3920   const FilePath some_file_one =
3921       temp_dir_.GetPath().Append(FPL("SomeFile (1).txt"));
3922   ASSERT_TRUE(
3923       File(some_file_one, File::FLAG_CREATE | File::FLAG_WRITE).IsValid());
3924 
3925   // This time the number 2 is needed to make it unique.
3926   EXPECT_EQ(GetUniquePathNumber(some_file), 2);
3927 }
3928 
TEST_F(FileUtilTest,GetUniquePathNumberTooManyFiles)3929 TEST_F(FileUtilTest, GetUniquePathNumberTooManyFiles) {
3930   // Create a file with the desired path.
3931   const FilePath some_file = temp_dir_.GetPath().Append(FPL("SomeFile.txt"));
3932   ASSERT_TRUE(File(some_file, File::FLAG_CREATE | File::FLAG_WRITE).IsValid());
3933 
3934   // Now create 100 collisions.
3935   for (int i = 1; i <= kMaxUniqueFiles; ++i) {
3936     ASSERT_EQ(GetUniquePathNumber(some_file), i);
3937     ASSERT_TRUE(File(temp_dir_.GetPath().AppendASCII(
3938                          StringPrintf("SomeFile (%d).txt", i)),
3939                      File::FLAG_CREATE | File::FLAG_WRITE)
3940                     .IsValid());
3941   }
3942 
3943   // Verify that the limit has been reached.
3944   EXPECT_EQ(GetUniquePathNumber(some_file), -1);
3945 }
3946 
TEST_F(FileUtilTest,PreReadFile_ExistingFile_NoSize)3947 TEST_F(FileUtilTest, PreReadFile_ExistingFile_NoSize) {
3948   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3949   CreateTextFile(text_file, bogus_content);
3950 
3951   EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false));
3952 }
3953 
TEST_F(FileUtilTest,PreReadFile_ExistingFile_ExactSize)3954 TEST_F(FileUtilTest, PreReadFile_ExistingFile_ExactSize) {
3955   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3956   CreateTextFile(text_file, bogus_content);
3957 
3958   EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false,
3959                           base::size(bogus_content)));
3960 }
3961 
TEST_F(FileUtilTest,PreReadFile_ExistingFile_OverSized)3962 TEST_F(FileUtilTest, PreReadFile_ExistingFile_OverSized) {
3963   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3964   CreateTextFile(text_file, bogus_content);
3965 
3966   EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false,
3967                           base::size(bogus_content) * 2));
3968 }
3969 
TEST_F(FileUtilTest,PreReadFile_ExistingFile_UnderSized)3970 TEST_F(FileUtilTest, PreReadFile_ExistingFile_UnderSized) {
3971   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3972   CreateTextFile(text_file, bogus_content);
3973 
3974   EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false,
3975                           base::size(bogus_content) / 2));
3976 }
3977 
TEST_F(FileUtilTest,PreReadFile_ExistingFile_ZeroSize)3978 TEST_F(FileUtilTest, PreReadFile_ExistingFile_ZeroSize) {
3979   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3980   CreateTextFile(text_file, bogus_content);
3981 
3982   EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false, /*max_bytes=*/0));
3983 }
3984 
TEST_F(FileUtilTest,PreReadFile_ExistingEmptyFile_NoSize)3985 TEST_F(FileUtilTest, PreReadFile_ExistingEmptyFile_NoSize) {
3986   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3987   CreateTextFile(text_file, L"");
3988   // The test just asserts that this doesn't crash. The Windows implementation
3989   // fails in this case, due to the base::MemoryMappedFile implementation and
3990   // the limitations of ::MapViewOfFile().
3991   PreReadFile(text_file, /*is_executable=*/false);
3992 }
3993 
TEST_F(FileUtilTest,PreReadFile_ExistingEmptyFile_ZeroSize)3994 TEST_F(FileUtilTest, PreReadFile_ExistingEmptyFile_ZeroSize) {
3995   FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file"));
3996   CreateTextFile(text_file, L"");
3997   EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false, /*max_bytes=*/0));
3998 }
3999 
TEST_F(FileUtilTest,PreReadFile_InexistentFile)4000 TEST_F(FileUtilTest, PreReadFile_InexistentFile) {
4001   FilePath inexistent_file = temp_dir_.GetPath().Append(FPL("inexistent_file"));
4002   EXPECT_FALSE(PreReadFile(inexistent_file, /*is_executable=*/false));
4003 }
4004 
4005 #endif  // !defined(OS_NACL_NONSFI)
4006 
4007 // Test that temp files obtained racily are all unique (no interference between
4008 // threads). Mimics file operations in DoLaunchChildTestProcess() to rule out
4009 // thread-safety issues @ https://crbug.com/826408#c17.
4010 #if defined(OS_FUCHSIA)
4011 // TODO(crbug.com/844416): Too slow to run on infra due to QEMU overloads.
4012 #define MAYBE_MultiThreadedTempFiles DISABLED_MultiThreadedTempFiles
4013 #else
4014 #define MAYBE_MultiThreadedTempFiles MultiThreadedTempFiles
4015 #endif
TEST(FileUtilMultiThreadedTest,MAYBE_MultiThreadedTempFiles)4016 TEST(FileUtilMultiThreadedTest, MAYBE_MultiThreadedTempFiles) {
4017   constexpr int kNumThreads = 64;
4018   constexpr int kNumWritesPerThread = 32;
4019 
4020   std::unique_ptr<Thread> threads[kNumThreads];
4021   for (auto& thread : threads) {
4022     thread = std::make_unique<Thread>("test worker");
4023     thread->Start();
4024   }
4025 
4026   // Wait until all threads are started for max parallelism.
4027   for (auto& thread : threads)
4028     thread->WaitUntilThreadStarted();
4029 
4030   const RepeatingClosure open_write_close_read = BindRepeating([]() {
4031     FilePath output_filename;
4032     ScopedFILE output_file(CreateAndOpenTemporaryFile(&output_filename));
4033     EXPECT_TRUE(output_file);
4034 
4035     const std::string content = GenerateGUID();
4036 #if defined(OS_WIN)
4037     HANDLE handle =
4038         reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(output_file.get())));
4039     DWORD bytes_written = 0;
4040     ::WriteFile(handle, content.c_str(), content.length(), &bytes_written,
4041                 NULL);
4042 #else
4043     size_t bytes_written =
4044         ::write(::fileno(output_file.get()), content.c_str(), content.length());
4045 #endif
4046     EXPECT_EQ(content.length(), bytes_written);
4047     ::fflush(output_file.get());
4048     output_file.reset();
4049 
4050     std::string output_file_contents;
4051     EXPECT_TRUE(ReadFileToString(output_filename, &output_file_contents))
4052         << output_filename;
4053 
4054     EXPECT_EQ(content, output_file_contents);
4055 
4056     DeleteFile(output_filename, false);
4057   });
4058 
4059   // Post tasks to each thread in a round-robin fashion to ensure as much
4060   // parallelism as possible.
4061   for (int i = 0; i < kNumWritesPerThread; ++i) {
4062     for (auto& thread : threads) {
4063       thread->task_runner()->PostTask(FROM_HERE, open_write_close_read);
4064     }
4065   }
4066 
4067   for (auto& thread : threads)
4068     thread->Stop();
4069 }
4070 
4071 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
4072 
TEST(ScopedFD,ScopedFDDoesClose)4073 TEST(ScopedFD, ScopedFDDoesClose) {
4074   int fds[2];
4075   char c = 0;
4076   ASSERT_EQ(0, pipe(fds));
4077   const int write_end = fds[1];
4078   ScopedFD read_end_closer(fds[0]);
4079   {
4080     ScopedFD write_end_closer(fds[1]);
4081   }
4082   // This is the only thread. This file descriptor should no longer be valid.
4083   int ret = close(write_end);
4084   EXPECT_EQ(-1, ret);
4085   EXPECT_EQ(EBADF, errno);
4086   // Make sure read(2) won't block.
4087   ASSERT_EQ(0, fcntl(fds[0], F_SETFL, O_NONBLOCK));
4088   // Reading the pipe should EOF.
4089   EXPECT_EQ(0, read(fds[0], &c, 1));
4090 }
4091 
4092 #if defined(GTEST_HAS_DEATH_TEST)
CloseWithScopedFD(int fd)4093 void CloseWithScopedFD(int fd) {
4094   ScopedFD fd_closer(fd);
4095 }
4096 #endif
4097 
TEST(ScopedFD,ScopedFDCrashesOnCloseFailure)4098 TEST(ScopedFD, ScopedFDCrashesOnCloseFailure) {
4099   int fds[2];
4100   ASSERT_EQ(0, pipe(fds));
4101   ScopedFD read_end_closer(fds[0]);
4102   EXPECT_EQ(0, IGNORE_EINTR(close(fds[1])));
4103 #if defined(GTEST_HAS_DEATH_TEST)
4104   // This is the only thread. This file descriptor should no longer be valid.
4105   // Trying to close it should crash. This is important for security.
4106   EXPECT_DEATH(CloseWithScopedFD(fds[1]), "");
4107 #endif
4108 }
4109 
4110 #endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
4111 
4112 }  // namespace
4113 
4114 }  // namespace base
4115