diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-10-13 13:24:50 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-10-14 10:57:25 +0000 |
commit | af3d4809763ef308f08ced947a73b624729ac7ea (patch) | |
tree | 4402b911e30383f6c6dace1e8cf3b8e85355db3a /chromium/base/files | |
parent | 0e8ff63a407fe323e215bb1a2c423c09a4747c8a (diff) |
BASELINE: Update Chromium to 47.0.2526.14
Also adding in sources needed for spellchecking.
Change-Id: Idd44170fa1616f26315188970a8d5ba7d472b18a
Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
Diffstat (limited to 'chromium/base/files')
-rw-r--r-- | chromium/base/files/OWNERS | 3 | ||||
-rw-r--r-- | chromium/base/files/dir_reader_posix_unittest.cc | 6 | ||||
-rw-r--r-- | chromium/base/files/file.h | 53 | ||||
-rw-r--r-- | chromium/base/files/file_enumerator_win.cc | 3 | ||||
-rw-r--r-- | chromium/base/files/file_path.cc | 12 | ||||
-rw-r--r-- | chromium/base/files/file_path_unittest.cc | 8 | ||||
-rw-r--r-- | chromium/base/files/file_path_watcher_linux.cc | 31 | ||||
-rw-r--r-- | chromium/base/files/file_path_watcher_win.cc | 4 | ||||
-rw-r--r-- | chromium/base/files/file_posix.cc | 43 | ||||
-rw-r--r-- | chromium/base/files/file_proxy_unittest.cc | 8 | ||||
-rw-r--r-- | chromium/base/files/file_tracing.h | 2 | ||||
-rw-r--r-- | chromium/base/files/file_unittest.cc | 71 | ||||
-rw-r--r-- | chromium/base/files/file_util_posix.cc | 12 | ||||
-rw-r--r-- | chromium/base/files/file_util_unittest.cc | 15 | ||||
-rw-r--r-- | chromium/base/files/important_file_writer.cc | 57 | ||||
-rw-r--r-- | chromium/base/files/important_file_writer.h | 26 | ||||
-rw-r--r-- | chromium/base/files/important_file_writer_unittest.cc | 10 |
17 files changed, 102 insertions, 262 deletions
diff --git a/chromium/base/files/OWNERS b/chromium/base/files/OWNERS deleted file mode 100644 index b99e8a2fc7a..00000000000 --- a/chromium/base/files/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -rvargas@chromium.org - -per-file file_path_watcher*=mnissler@chromium.org diff --git a/chromium/base/files/dir_reader_posix_unittest.cc b/chromium/base/files/dir_reader_posix_unittest.cc index 0685031a982..2e181b3d851 100644 --- a/chromium/base/files/dir_reader_posix_unittest.cc +++ b/chromium/base/files/dir_reader_posix_unittest.cc @@ -10,6 +10,7 @@ #include <string.h> #include <unistd.h> +#include "base/files/scoped_temp_dir.h" #include "base/logging.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,8 +26,9 @@ TEST(DirReaderPosixUnittest, Read) { if (DirReaderPosix::IsFallback()) return; - char kDirTemplate[] = "/tmp/org.chromium.dir-reader-posix-XXXXXX"; - const char* dir = mkdtemp(kDirTemplate); + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + const char* dir = temp_dir.path().value().c_str(); ASSERT_TRUE(dir); const int prev_wd = open(".", O_RDONLY | O_DIRECTORY); diff --git a/chromium/base/files/file.h b/chromium/base/files/file.h index cba43536356..976188b232e 100644 --- a/chromium/base/files/file.h +++ b/chromium/base/files/file.h @@ -21,7 +21,6 @@ #include "base/files/file_path.h" #include "base/files/file_tracing.h" #include "base/files/scoped_file.h" -#include "base/gtest_prod_util.h" #include "base/move.h" #include "base/time/time.h" @@ -29,8 +28,6 @@ #include "base/win/scoped_handle.h" #endif -FORWARD_DECLARE_TEST(FileTest, MemoryCorruption); - namespace base { #if defined(OS_WIN) @@ -306,55 +303,8 @@ class BASE_EXPORT File { static std::string ErrorToString(Error error); private: - FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption); - friend class FileTracing::ScopedTrace; -#if defined(OS_POSIX) - // Encloses a single ScopedFD, saving a cheap tamper resistent memory checksum - // alongside it. This checksum is validated at every access, allowing early - // detection of memory corruption. - - // TODO(gavinp): This is in place temporarily to help us debug - // https://crbug.com/424562 , which can't be reproduced in valgrind. Remove - // this code after we have fixed this issue. - class MemoryCheckingScopedFD { - public: - MemoryCheckingScopedFD(); - MemoryCheckingScopedFD(int fd); - ~MemoryCheckingScopedFD(); - - bool is_valid() const { Check(); return file_.is_valid(); } - int get() const { Check(); return file_.get(); } - - void reset() { Check(); file_.reset(); UpdateChecksum(); } - void reset(int fd) { Check(); file_.reset(fd); UpdateChecksum(); } - int release() { - Check(); - int fd = file_.release(); - UpdateChecksum(); - return fd; - } - - private: - FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption); - - // Computes the checksum for the current value of |file_|. Returns via an - // out parameter to guard against implicit conversions of unsigned integral - // types. - void ComputeMemoryChecksum(unsigned int* out_checksum) const; - - // Confirms that the current |file_| and |file_memory_checksum_| agree, - // failing a CHECK if they do not. - void Check() const; - - void UpdateChecksum(); - - ScopedFD file_; - unsigned int file_memory_checksum_; - }; -#endif - // Creates or opens the given file. Only called if |path| has no // traversal ('..') components. void DoInitialize(const FilePath& path, uint32 flags); @@ -368,7 +318,7 @@ class BASE_EXPORT File { #if defined(OS_WIN) win::ScopedHandle file_; #elif defined(OS_POSIX) - MemoryCheckingScopedFD file_; + ScopedFD file_; #endif // A path to use for tracing purposes. Set if file tracing is enabled during @@ -386,3 +336,4 @@ class BASE_EXPORT File { } // namespace base #endif // BASE_FILES_FILE_H_ + diff --git a/chromium/base/files/file_enumerator_win.cc b/chromium/base/files/file_enumerator_win.cc index ae41a4600d3..90db7f5729e 100644 --- a/chromium/base/files/file_enumerator_win.cc +++ b/chromium/base/files/file_enumerator_win.cc @@ -30,7 +30,8 @@ int64 FileEnumerator::FileInfo::GetSize() const { ULARGE_INTEGER size; size.HighPart = find_data_.nFileSizeHigh; size.LowPart = find_data_.nFileSizeLow; - DCHECK_LE(size.QuadPart, std::numeric_limits<int64>::max()); + DCHECK_LE(size.QuadPart, + static_cast<ULONGLONG>(std::numeric_limits<int64>::max())); return static_cast<int64>(size.QuadPart); } diff --git a/chromium/base/files/file_path.cc b/chromium/base/files/file_path.cc index 92123533aaa..18775ed9ca9 100644 --- a/chromium/base/files/file_path.cc +++ b/chromium/base/files/file_path.cc @@ -10,9 +10,6 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/pickle.h" - -// These includes are just for the *Hack functions, and should be removed -// when those functions are removed. #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" @@ -1259,11 +1256,12 @@ int FilePath::CompareIgnoreCase(StringPieceType string1, #else // << WIN. MACOSX | other (POSIX) >> -// Generic (POSIX) implementation of file string comparison. -// TODO(rolandsteiner) check if this is sufficient/correct. +// Generic Posix system comparisons. int FilePath::CompareIgnoreCase(StringPieceType string1, StringPieceType string2) { - int comparison = strcasecmp(string1.data(), string2.data()); + // Specifically need null termianted strings for this API call. + int comparison = strcasecmp(string1.as_string().c_str(), + string2.as_string().c_str()); if (comparison < 0) return -1; if (comparison > 0) @@ -1316,7 +1314,7 @@ FilePath FilePath::NormalizePathSeparatorsTo(CharType separator) const { #if defined(OS_ANDROID) bool FilePath::IsContentUri() const { - return StartsWithASCII(path_, "content://", false /*case_sensitive*/); + return StartsWith(path_, "content://", base::CompareCase::INSENSITIVE_ASCII); } #endif diff --git a/chromium/base/files/file_path_unittest.cc b/chromium/base/files/file_path_unittest.cc index 60eaa8f002f..bc0e8432e0e 100644 --- a/chromium/base/files/file_path_unittest.cc +++ b/chromium/base/files/file_path_unittest.cc @@ -10,6 +10,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" +#if defined(OS_POSIX) +#include "base/test/scoped_locale.h" +#endif + // This macro helps avoid wrapped lines in the test structs. #define FPL(x) FILE_PATH_LITERAL(x) @@ -1126,6 +1130,10 @@ TEST_F(FilePathTest, FromUTF8Unsafe_And_AsUTF8Unsafe) { "\xEF\xBC\xA1\xEF\xBC\xA2\xEF\xBC\xA3.txt" }, }; +#if !defined(SYSTEM_NATIVE_UTF8) && defined(OS_LINUX) + ScopedLocale locale("en_US.UTF-8"); +#endif + for (size_t i = 0; i < arraysize(cases); ++i) { // Test FromUTF8Unsafe() works. FilePath from_utf8 = FilePath::FromUTF8Unsafe(cases[i].utf8); diff --git a/chromium/base/files/file_path_watcher_linux.cc b/chromium/base/files/file_path_watcher_linux.cc index ba2f1d96c84..6dfc0a6403e 100644 --- a/chromium/base/files/file_path_watcher_linux.cc +++ b/chromium/base/files/file_path_watcher_linux.cc @@ -28,6 +28,7 @@ #include "base/memory/scoped_ptr.h" #include "base/posix/eintr_wrapper.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/synchronization/lock.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" @@ -167,9 +168,8 @@ class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate, void RemoveRecursiveWatches(); // |path| is a symlink to a non-existent target. Attempt to add a watch to - // the link target's parent directory. Returns true and update |watch_entry| - // on success. - bool AddWatchForBrokenSymlink(const FilePath& path, WatchEntry* watch_entry); + // the link target's parent directory. Update |watch_entry| on success. + void AddWatchForBrokenSymlink(const FilePath& path, WatchEntry* watch_entry); bool HasValidWatchVector() const; @@ -513,21 +513,19 @@ void FilePathWatcherImpl::UpdateWatches() { // Walk the list of watches and update them as we go. FilePath path(FILE_PATH_LITERAL("/")); - bool path_valid = true; for (size_t i = 0; i < watches_.size(); ++i) { WatchEntry& watch_entry = watches_[i]; InotifyReader::Watch old_watch = watch_entry.watch; watch_entry.watch = InotifyReader::kInvalidWatch; watch_entry.linkname.clear(); - if (path_valid) { - watch_entry.watch = g_inotify_reader.Get().AddWatch(path, this); - if (watch_entry.watch == InotifyReader::kInvalidWatch) { - if (IsLink(path)) { - path_valid = AddWatchForBrokenSymlink(path, &watch_entry); - } else { - path_valid = false; - } - } + watch_entry.watch = g_inotify_reader.Get().AddWatch(path, this); + if (watch_entry.watch == InotifyReader::kInvalidWatch) { + // Ignore the error code (beyond symlink handling) to attempt to add + // watches on accessible children of unreadable directories. Note that + // this is a best-effort attempt; we may not catch events in this + // scenario. + if (IsLink(path)) + AddWatchForBrokenSymlink(path, &watch_entry); } if (old_watch != watch_entry.watch) g_inotify_reader.Get().RemoveWatch(old_watch, this); @@ -643,12 +641,12 @@ void FilePathWatcherImpl::RemoveRecursiveWatches() { recursive_watches_by_path_.clear(); } -bool FilePathWatcherImpl::AddWatchForBrokenSymlink(const FilePath& path, +void FilePathWatcherImpl::AddWatchForBrokenSymlink(const FilePath& path, WatchEntry* watch_entry) { DCHECK_EQ(InotifyReader::kInvalidWatch, watch_entry->watch); FilePath link; if (!ReadSymbolicLink(path, &link)) - return false; + return; if (!link.IsAbsolute()) link = path.DirName().Append(link); @@ -664,11 +662,10 @@ bool FilePathWatcherImpl::AddWatchForBrokenSymlink(const FilePath& path, // exist. Ideally we should make sure we've watched all the components of // the symlink path for changes. See crbug.com/91561 for details. DPLOG(WARNING) << "Watch failed for " << link.DirName().value(); - return false; + return; } watch_entry->watch = watch; watch_entry->linkname = link.BaseName().value(); - return true; } bool FilePathWatcherImpl::HasValidWatchVector() const { diff --git a/chromium/base/files/file_path_watcher_win.cc b/chromium/base/files/file_path_watcher_win.cc index 081698f8df1..3f37cec51c1 100644 --- a/chromium/base/files/file_path_watcher_win.cc +++ b/chromium/base/files/file_path_watcher_win.cc @@ -106,7 +106,7 @@ bool FilePathWatcherImpl::Watch(const FilePath& path, if (!UpdateWatch()) return false; - watcher_.StartWatching(handle_, this); + watcher_.StartWatchingOnce(handle_, this); return true; } @@ -198,7 +198,7 @@ void FilePathWatcherImpl::OnObjectSignaled(HANDLE object) { // The watch may have been cancelled by the callback. if (handle_ != INVALID_HANDLE_VALUE) - watcher_.StartWatching(handle_, this); + watcher_.StartWatchingOnce(handle_, this); } // static diff --git a/chromium/base/files/file_posix.cc b/chromium/base/files/file_posix.cc index 7fb617c3f9d..a5aee01aa29 100644 --- a/chromium/base/files/file_posix.cc +++ b/chromium/base/files/file_posix.cc @@ -420,49 +420,6 @@ File::Error File::OSErrorToFileError(int saved_errno) { } } -File::MemoryCheckingScopedFD::MemoryCheckingScopedFD() { - UpdateChecksum(); -} - -File::MemoryCheckingScopedFD::MemoryCheckingScopedFD(int fd) : file_(fd) { - UpdateChecksum(); -} - -File::MemoryCheckingScopedFD::~MemoryCheckingScopedFD() {} - -// static -void File::MemoryCheckingScopedFD::ComputeMemoryChecksum( - unsigned int* out_checksum) const { - // Use a single iteration of a linear congruentional generator (lcg) to - // provide a cheap checksum unlikely to be accidentally matched by a random - // memory corruption. - - // By choosing constants that satisfy the Hull-Duebell Theorem on lcg cycle - // length, we insure that each distinct fd value maps to a distinct checksum, - // which maximises the utility of our checksum. - - // This code uses "unsigned int" throughout for its defined modular semantics, - // which implicitly gives us a divisor that is a power of two. - - const unsigned int kMultiplier = 13035 * 4 + 1; - COMPILE_ASSERT(((kMultiplier - 1) & 3) == 0, pred_must_be_multiple_of_four); - const unsigned int kIncrement = 1595649551; - COMPILE_ASSERT(kIncrement & 1, must_be_coprime_to_powers_of_two); - - *out_checksum = - static_cast<unsigned int>(file_.get()) * kMultiplier + kIncrement; -} - -void File::MemoryCheckingScopedFD::Check() const { - unsigned int computed_checksum; - ComputeMemoryChecksum(&computed_checksum); - CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory"; -} - -void File::MemoryCheckingScopedFD::UpdateChecksum() { - ComputeMemoryChecksum(&file_memory_checksum_); -} - // NaCl doesn't implement system calls to open files directly. #if !defined(OS_NACL) // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? diff --git a/chromium/base/files/file_proxy_unittest.cc b/chromium/base/files/file_proxy_unittest.cc index df0bbc869c2..efe5c924299 100644 --- a/chromium/base/files/file_proxy_unittest.cc +++ b/chromium/base/files/file_proxy_unittest.cc @@ -287,7 +287,13 @@ TEST_F(FileProxyTest, WriteAndFlush) { } } -TEST_F(FileProxyTest, SetTimes) { +#if defined(OS_ANDROID) +// Flaky on Android, see http://crbug.com/489602 +#define MAYBE_SetTimes DISABLED_SetTimes +#else +#define MAYBE_SetTimes SetTimes +#endif +TEST_F(FileProxyTest, MAYBE_SetTimes) { FileProxy proxy(file_task_runner()); CreateProxy( File::FLAG_CREATE | File::FLAG_WRITE | File::FLAG_WRITE_ATTRIBUTES, diff --git a/chromium/base/files/file_tracing.h b/chromium/base/files/file_tracing.h index 92324c9475a..d37c21d9ed4 100644 --- a/chromium/base/files/file_tracing.h +++ b/chromium/base/files/file_tracing.h @@ -30,6 +30,8 @@ class BASE_EXPORT FileTracing { class Provider { public: + virtual ~Provider() = default; + // Whether the file tracing category is currently enabled. virtual bool FileTracingCategoryIsEnabled() const = 0; diff --git a/chromium/base/files/file_unittest.cc b/chromium/base/files/file_unittest.cc index 5c594242bc8..67dbbfd1ec8 100644 --- a/chromium/base/files/file_unittest.cc +++ b/chromium/base/files/file_unittest.cc @@ -5,7 +5,6 @@ #include "base/files/file.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" @@ -495,7 +494,7 @@ TEST(FileTest, GetInfoForDirectory) { base::File dir( ::CreateFile(empty_dir.value().c_str(), - FILE_ALL_ACCESS, + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, @@ -510,71 +509,3 @@ TEST(FileTest, GetInfoForDirectory) { EXPECT_EQ(0, info.size); } #endif // defined(OS_WIN) - -#if defined(OS_POSIX) && defined(GTEST_HAS_DEATH_TEST) -TEST(FileTest, MemoryCorruption) { - { - // Test that changing the checksum value is detected. - base::File file; - EXPECT_NE(file.file_.file_memory_checksum_, - implicit_cast<unsigned int>(file.GetPlatformFile())); - file.file_.file_memory_checksum_ = file.GetPlatformFile(); - EXPECT_DEATH(file.IsValid(), ""); - - file.file_.UpdateChecksum(); // Do not crash on File::~File(). - } - - { - // Test that changing the file descriptor value is detected. - base::File file; - file.file_.file_.reset(17); - EXPECT_DEATH(file.IsValid(), ""); - - // Do not crash on File::~File(). - ignore_result(file.file_.file_.release()); - file.file_.UpdateChecksum(); - } - - { - // Test that GetPlatformFile() checks for corruption. - base::File file; - file.file_.file_memory_checksum_ = file.GetPlatformFile(); - EXPECT_DEATH(file.GetPlatformFile(), ""); - - file.file_.UpdateChecksum(); // Do not crash on File::~File(). - } - - { - // Test that the base::File destructor checks for corruption. - scoped_ptr<base::File> file(new File()); - file->file_.file_memory_checksum_ = file->GetPlatformFile(); - EXPECT_DEATH(file.reset(), ""); - - // Do not crash on this thread's destructor call. - file->file_.UpdateChecksum(); - } - - { - // Test that the base::File constructor checks for corruption. - base::File file; - file.file_.file_memory_checksum_ = file.GetPlatformFile(); - EXPECT_DEATH(File f(file.Pass()), ""); - - file.file_.UpdateChecksum(); // Do not crash on File::~File(). - } - - { - // Test that doing IO checks for corruption. - base::File file; - file.file_.file_.reset(17); // A fake open FD value. - - EXPECT_DEATH(file.Seek(File::FROM_BEGIN, 0), ""); - EXPECT_DEATH(file.Read(0, NULL, 0), ""); - EXPECT_DEATH(file.ReadAtCurrentPos(NULL, 0), ""); - EXPECT_DEATH(file.Write(0, NULL, 0), ""); - - ignore_result(file.file_.file_.release()); - file.file_.UpdateChecksum(); - } -} -#endif // defined(OS_POSIX) diff --git a/chromium/base/files/file_util_posix.cc b/chromium/base/files/file_util_posix.cc index a8c5d44f9c7..ffa79a45f42 100644 --- a/chromium/base/files/file_util_posix.cc +++ b/chromium/base/files/file_util_posix.cc @@ -24,8 +24,6 @@ #if defined(OS_MACOSX) #include <AvailabilityMacros.h> #include "base/mac/foundation_util.h" -#elif !defined(OS_CHROMEOS) && defined(USE_GLIB) -#include <glib.h> // for g_get_home_dir() #endif #include "base/basictypes.h" @@ -478,16 +476,6 @@ FilePath GetHomeDir() { #if defined(OS_ANDROID) DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; -#elif defined(USE_GLIB) && !defined(OS_CHROMEOS) - // g_get_home_dir calls getpwent, which can fall through to LDAP calls so - // this may do I/O. However, it should be rare that $HOME is not defined and - // this is typically called from the path service which has no threading - // restrictions. The path service will cache the result which limits the - // badness of blocking on I/O. As a result, we don't have a thread - // restriction here. - home_dir = g_get_home_dir(); - if (home_dir && home_dir[0]) - return FilePath(home_dir); #endif FilePath rv; diff --git a/chromium/base/files/file_util_unittest.cc b/chromium/base/files/file_util_unittest.cc index 52581f8ce43..933cb7f46e5 100644 --- a/chromium/base/files/file_util_unittest.cc +++ b/chromium/base/files/file_util_unittest.cc @@ -134,7 +134,7 @@ class ReparsePoint { ReparsePoint(const FilePath& source, const FilePath& target) { dir_.Set( ::CreateFile(source.value().c_str(), - FILE_ALL_ACCESS, + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, @@ -244,15 +244,6 @@ std::wstring ReadTextFile(const FilePath& filename) { return std::wstring(contents); } -#if defined(OS_WIN) -uint64 FileTimeAsUint64(const FILETIME& ft) { - ULARGE_INTEGER u; - u.LowPart = ft.dwLowDateTime; - u.HighPart = ft.dwHighDateTime; - return u.QuadPart; -} -#endif - TEST_F(FileUtilTest, FileAndDirectorySize) { // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize // should return 53 bytes. @@ -435,8 +426,8 @@ TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) { TEST_F(FileUtilTest, DevicePathToDriveLetter) { // Get a drive letter. - std::wstring real_drive_letter = temp_dir_.path().value().substr(0, 2); - StringToUpperASCII(&real_drive_letter); + string16 real_drive_letter = + ToUpperASCII(temp_dir_.path().value().substr(0, 2)); if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) { LOG(ERROR) << "Can't get a drive letter to test with."; return; diff --git a/chromium/base/files/important_file_writer.cc b/chromium/base/files/important_file_writer.cc index 814fc7b9add..1529107bdf3 100644 --- a/chromium/base/files/important_file_writer.cc +++ b/chromium/base/files/important_file_writer.cc @@ -16,6 +16,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/histogram.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/task_runner.h" @@ -47,8 +48,7 @@ void LogFailure(const FilePath& path, TempFileFailure failure_code, const std::string& message) { UMA_HISTOGRAM_ENUMERATION("ImportantFile.TempFileFailures", failure_code, TEMP_FILE_FAILURE_MAX); - DPLOG(WARNING) << "temp file failure: " << path.value().c_str() - << " : " << message; + DPLOG(WARNING) << "temp file failure: " << path.value() << " : " << message; } // Helper function to call WriteFileAtomically() with a scoped_ptr<std::string>. @@ -72,16 +72,16 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path, char path[128]; } file_info; file_info.data_size = data.size(); - base::strlcpy(file_info.path, path.value().c_str(), - arraysize(file_info.path)); - base::debug::Alias(&file_info); + strlcpy(file_info.path, path.value().c_str(), arraysize(file_info.path)); + debug::Alias(&file_info); #endif + // Write the data to a temp file then rename to avoid data loss if we crash // while writing the file. Ensure that the temp file is on the same volume // as target file, so it can be moved in one step, and that the temp file // is securely created. FilePath tmp_file_path; - if (!base::CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) { + if (!CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) { LogFailure(path, FAILED_CREATING, "could not create temporary file"); return false; } @@ -92,29 +92,28 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path, return false; } - // If this happens in the wild something really bad is going on. - CHECK_LE(data.length(), static_cast<size_t>(kint32max)); - int bytes_written = tmp_file.Write(0, data.data(), - static_cast<int>(data.length())); + // If this fails in the wild, something really bad is going on. + const int data_length = checked_cast<int32_t>(data.length()); + int bytes_written = tmp_file.Write(0, data.data(), data_length); bool flush_success = tmp_file.Flush(); tmp_file.Close(); - if (bytes_written < static_cast<int>(data.length())) { + if (bytes_written < data_length) { LogFailure(path, FAILED_WRITING, "error writing, bytes_written=" + IntToString(bytes_written)); - base::DeleteFile(tmp_file_path, false); + DeleteFile(tmp_file_path, false); return false; } if (!flush_success) { LogFailure(path, FAILED_FLUSHING, "error flushing"); - base::DeleteFile(tmp_file_path, false); + DeleteFile(tmp_file_path, false); return false; } - if (!base::ReplaceFile(tmp_file_path, path, NULL)) { + if (!ReplaceFile(tmp_file_path, path, nullptr)) { LogFailure(path, FAILED_RENAMING, "could not rename temporary file"); - base::DeleteFile(tmp_file_path, false); + DeleteFile(tmp_file_path, false); return false; } @@ -123,11 +122,21 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path, ImportantFileWriter::ImportantFileWriter( const FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& task_runner) + const scoped_refptr<SequencedTaskRunner>& task_runner) + : ImportantFileWriter( + path, + task_runner, + TimeDelta::FromMilliseconds(kDefaultCommitIntervalMs)) { +} + +ImportantFileWriter::ImportantFileWriter( + const FilePath& path, + const scoped_refptr<SequencedTaskRunner>& task_runner, + TimeDelta interval) : path_(path), task_runner_(task_runner), - serializer_(NULL), - commit_interval_(TimeDelta::FromMilliseconds(kDefaultCommitIntervalMs)), + serializer_(nullptr), + commit_interval_(interval), weak_factory_(this) { DCHECK(CalledOnValidThread()); DCHECK(task_runner_); @@ -147,7 +156,7 @@ bool ImportantFileWriter::HasPendingWrite() const { void ImportantFileWriter::WriteNow(scoped_ptr<std::string> data) { DCHECK(CalledOnValidThread()); - if (data->length() > static_cast<size_t>(kint32max)) { + if (!IsValueInRangeForNumericType<int32_t>(data->length())) { NOTREACHED(); return; } @@ -185,13 +194,13 @@ void ImportantFileWriter::DoScheduledWrite() { WriteNow(data.Pass()); } else { DLOG(WARNING) << "failed to serialize data to be saved in " - << path_.value().c_str(); + << path_.value(); } - serializer_ = NULL; + serializer_ = nullptr; } void ImportantFileWriter::RegisterOnNextSuccessfulWriteCallback( - const base::Closure& on_next_successful_write) { + const Closure& on_next_successful_write) { DCHECK(on_next_successful_write_.is_null()); on_next_successful_write_ = on_next_successful_write; } @@ -203,7 +212,7 @@ bool ImportantFileWriter::PostWriteTask(const Callback<bool()>& task) { // suppressing all of those is unrealistic hence we avoid most of them by // using PostTask() in the typical scenario below. if (!on_next_successful_write_.is_null()) { - return base::PostTaskAndReplyWithResult( + return PostTaskAndReplyWithResult( task_runner_.get(), FROM_HERE, MakeCriticalClosure(task), @@ -212,7 +221,7 @@ bool ImportantFileWriter::PostWriteTask(const Callback<bool()>& task) { } return task_runner_->PostTask( FROM_HERE, - MakeCriticalClosure(base::Bind(IgnoreResult(task)))); + MakeCriticalClosure(Bind(IgnoreResult(task)))); } void ImportantFileWriter::ForwardSuccessfulWrite(bool result) { diff --git a/chromium/base/files/important_file_writer.h b/chromium/base/files/important_file_writer.h index 99f1a7c6814..7c6160a5f9f 100644 --- a/chromium/base/files/important_file_writer.h +++ b/chromium/base/files/important_file_writer.h @@ -62,9 +62,13 @@ class BASE_EXPORT ImportantFileWriter : public NonThreadSafe { // |task_runner| is the SequencedTaskRunner instance where on which we will // execute file I/O operations. // All non-const methods, ctor and dtor must be called on the same thread. - ImportantFileWriter( - const FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& task_runner); + ImportantFileWriter(const FilePath& path, + const scoped_refptr<SequencedTaskRunner>& task_runner); + + // Same as above, but with a custom commit interval. + ImportantFileWriter(const FilePath& path, + const scoped_refptr<SequencedTaskRunner>& task_runner, + TimeDelta interval); // You have to ensure that there are no pending writes at the moment // of destruction. @@ -77,7 +81,7 @@ class BASE_EXPORT ImportantFileWriter : public NonThreadSafe { bool HasPendingWrite() const; // Save |data| to target filename. Does not block. If there is a pending write - // scheduled by ScheduleWrite, it is cancelled. + // scheduled by ScheduleWrite(), it is cancelled. void WriteNow(scoped_ptr<std::string> data); // Schedule a save to target filename. Data will be serialized and saved @@ -94,16 +98,12 @@ class BASE_EXPORT ImportantFileWriter : public NonThreadSafe { // Registers |on_next_successful_write| to be called once, on the next // successful write event. Only one callback can be set at once. void RegisterOnNextSuccessfulWriteCallback( - const base::Closure& on_next_successful_write); + const Closure& on_next_successful_write); TimeDelta commit_interval() const { return commit_interval_; } - void set_commit_interval(const TimeDelta& interval) { - commit_interval_ = interval; - } - private: // Helper method for WriteNow(). bool PostWriteTask(const Callback<bool()>& task); @@ -113,22 +113,22 @@ class BASE_EXPORT ImportantFileWriter : public NonThreadSafe { void ForwardSuccessfulWrite(bool result); // Invoked once and then reset on the next successful write event. - base::Closure on_next_successful_write_; + Closure on_next_successful_write_; // Path being written to. const FilePath path_; // TaskRunner for the thread on which file I/O can be done. - const scoped_refptr<base::SequencedTaskRunner> task_runner_; + const scoped_refptr<SequencedTaskRunner> task_runner_; // Timer used to schedule commit after ScheduleWrite. - OneShotTimer<ImportantFileWriter> timer_; + OneShotTimer timer_; // Serializer which will provide the data to be saved. DataSerializer* serializer_; // Time delta after which scheduled data will be written to disk. - TimeDelta commit_interval_; + const TimeDelta commit_interval_; WeakPtrFactory<ImportantFileWriter> weak_factory_; diff --git a/chromium/base/files/important_file_writer_unittest.cc b/chromium/base/files/important_file_writer_unittest.cc index d376cdc35ab..71900c93d5e 100644 --- a/chromium/base/files/important_file_writer_unittest.cc +++ b/chromium/base/files/important_file_writer_unittest.cc @@ -145,8 +145,9 @@ TEST_F(ImportantFileWriterTest, BasicWithSuccessfulWriteObserver) { } TEST_F(ImportantFileWriterTest, ScheduleWrite) { - ImportantFileWriter writer(file_, ThreadTaskRunnerHandle::Get()); - writer.set_commit_interval(TimeDelta::FromMilliseconds(25)); + ImportantFileWriter writer(file_, + ThreadTaskRunnerHandle::Get(), + TimeDelta::FromMilliseconds(25)); EXPECT_FALSE(writer.HasPendingWrite()); DataSerializer serializer("foo"); writer.ScheduleWrite(&serializer); @@ -177,8 +178,9 @@ TEST_F(ImportantFileWriterTest, DoScheduledWrite) { } TEST_F(ImportantFileWriterTest, BatchingWrites) { - ImportantFileWriter writer(file_, ThreadTaskRunnerHandle::Get()); - writer.set_commit_interval(TimeDelta::FromMilliseconds(25)); + ImportantFileWriter writer(file_, + ThreadTaskRunnerHandle::Get(), + TimeDelta::FromMilliseconds(25)); DataSerializer foo("foo"), bar("bar"), baz("baz"); writer.ScheduleWrite(&foo); writer.ScheduleWrite(&bar); |