summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorkaliamoorthi@chromium.org <kaliamoorthi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-18 16:31:51 +0000
committerkaliamoorthi@chromium.org <kaliamoorthi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-18 16:31:51 +0000
commit0710fdd560c67f86874fd797c081c7fd032bdef5 (patch)
tree0c733c8eae72b95166f52bfaf1e88407f80289ed /base
parent68d3fc19891f9864040264e6d6657720b886ac59 (diff)
downloadchromium_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.cc27
-rw-r--r--base/file_util.h18
-rw-r--r--base/file_util_unittest.cc45
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"));