diff options
author | kaliamoorthi@chromium.org <kaliamoorthi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-18 16:31:51 +0000 |
---|---|---|
committer | kaliamoorthi@chromium.org <kaliamoorthi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-18 16:31:51 +0000 |
commit | 0710fdd560c67f86874fd797c081c7fd032bdef5 (patch) | |
tree | 0c733c8eae72b95166f52bfaf1e88407f80289ed /base | |
parent | 68d3fc19891f9864040264e6d6657720b886ac59 (diff) | |
download | chromium_src-0710fdd560c67f86874fd797c081c7fd032bdef5.zip chromium_src-0710fdd560c67f86874fd797c081c7fd032bdef5.tar.gz chromium_src-0710fdd560c67f86874fd797c081c7fd032bdef5.tar.bz2 |
Added new ReadFileToString API with a max_size argument
The CL creates a new API that takes a max_size argument. When the file size exceed the max_size, the API primes the cache and returns false.
BUG=339417
Review URL: https://codereview.chromium.org/157593005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251771 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/file_util.cc | 27 | ||||
-rw-r--r-- | base/file_util.h | 18 | ||||
-rw-r--r-- | base/file_util_unittest.cc | 45 |
3 files changed, 85 insertions, 5 deletions
diff --git a/base/file_util.cc b/base/file_util.cc index e44f713..87b9afb99 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -10,6 +10,7 @@ #include <stdio.h> #include <fstream> +#include <limits> #include "base/files/file_enumerator.h" #include "base/files/file_path.h" @@ -126,7 +127,11 @@ bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) { return true; } -bool ReadFileToString(const FilePath& path, std::string* contents) { +bool ReadFileToString(const FilePath& path, + std::string* contents, + size_t max_size) { + if (contents) + contents->clear(); if (path.ReferencesParent()) return false; FILE* file = OpenFile(path, "rb"); @@ -136,13 +141,29 @@ bool ReadFileToString(const FilePath& path, std::string* contents) { char buf[1 << 16]; size_t len; + size_t size = 0; + bool read_status = true; + + // Many files supplied in |path| have incorrect size (proc files etc). + // Hence, the file is read sequentially as opposed to a one-shot read. while ((len = fread(buf, 1, sizeof(buf), file)) > 0) { if (contents) - contents->append(buf, len); + contents->append(buf, std::min(len, max_size - size)); + + if ((max_size - size) < len) { + read_status = false; + break; + } + + size += len; } CloseFile(file); - return true; + return read_status; +} + +bool ReadFileToString(const FilePath& path, std::string* contents) { + return ReadFileToString(path, contents, std::numeric_limits<size_t>::max()); } bool IsDirectoryEmpty(const FilePath& dir_path) { diff --git a/base/file_util.h b/base/file_util.h index 7690703..9143c60 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -139,10 +139,24 @@ BASE_EXPORT bool TextContentsEqual(const FilePath& filename1, // Read the file at |path| into |contents|, returning true on success. // This function fails if the |path| contains path traversal components ('..'). // |contents| may be NULL, in which case this function is useful for its -// side effect of priming the disk cache. -// Useful for unit tests. +// side effect of priming the disk cache, which is useful for unit tests. +// The function replaces rather than append to |contents|, further |contents| +// could be cleared on error. BASE_EXPORT bool ReadFileToString(const FilePath& path, std::string* contents); +// Read the file at |path| into |contents|, returning true on success. +// This function has an additional check on the maximum size of the file. +// When the file size is greater than |max_size|, the function reads |max_size| +// bytes into |contents| and returns false. +// This function fails if the |path| contains path traversal components ('..'). +// |contents| may be NULL, in which case this function is useful for its +// side effect of priming the disk cache, which is useful for unit tests. +// The function replaces rather than append to |contents|, further |contents| +// could be cleared on error. +BASE_EXPORT bool ReadFileToString(const FilePath& path, + std::string* contents, + size_t max_size); + #if defined(OS_POSIX) // Read exactly |bytes| bytes from file descriptor |fd|, storing the result diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc index df447ab..d36d4b2 100644 --- a/base/file_util_unittest.cc +++ b/base/file_util_unittest.cc @@ -1941,6 +1941,51 @@ TEST_F(FileUtilTest, AppendToFile) { EXPECT_EQ(L"hellohello", read_content); } +TEST_F(FileUtilTest, ReadFileToString) { + const char kTestData[] = "0123"; + std::string data; + + FilePath file_path = + temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileToStringTest")); + + ASSERT_EQ(4, file_util::WriteFile(file_path, kTestData, 4)); + + EXPECT_TRUE(ReadFileToString(file_path, &data)); + EXPECT_EQ(kTestData, data); + + data = "temp"; + EXPECT_FALSE(ReadFileToString(file_path, &data, 0)); + EXPECT_EQ(data.length(), 0u); + + data = "temp"; + EXPECT_FALSE(ReadFileToString(file_path, &data, 2)); + EXPECT_EQ("01", data); + + data.clear(); + EXPECT_FALSE(ReadFileToString(file_path, &data, 3)); + EXPECT_EQ("012", data); + + data.clear(); + EXPECT_TRUE(ReadFileToString(file_path, &data, 4)); + EXPECT_EQ("0123", data); + + data.clear(); + EXPECT_TRUE(ReadFileToString(file_path, &data, 6)); + EXPECT_EQ("0123", data); + + EXPECT_TRUE(ReadFileToString(file_path, NULL, 6)); + + EXPECT_TRUE(ReadFileToString(file_path, NULL)); + + EXPECT_TRUE(base::DeleteFile(file_path, false)); + + EXPECT_FALSE(ReadFileToString(file_path, &data)); + EXPECT_EQ(data.length(), 0u); + + EXPECT_FALSE(ReadFileToString(file_path, &data, 6)); + EXPECT_EQ(data.length(), 0u); +} + TEST_F(FileUtilTest, TouchFile) { FilePath data_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); |