summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-10-30 17:48:15 +1100
committerMaxime Coste <mawww@kakoune.org>2017-10-30 18:58:47 +1100
commitcd215ccee90aef19d51f403a76f33c7b7eeecfce (patch)
treecd0e6cb5ec9e27d5264f8862a63f55d557ba3466
parent40eb598065f9c6e1a5ab9ee28a2f58a56bf773e6 (diff)
Do not allow opening files whose size we cannot express in an int
-rw-r--r--src/file.cc12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/file.cc b/src/file.cc
index b95972b3..c5f60c1b 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -185,6 +185,7 @@ String read_file(StringView filename, bool text)
}
MappedFile::MappedFile(StringView filename)
+ : data{nullptr}
{
fd = open(filename.zstr(), O_RDONLY | O_NONBLOCK);
if (fd == -1)
@@ -194,14 +195,23 @@ MappedFile::MappedFile(StringView filename)
if (S_ISDIR(st.st_mode))
throw file_access_error(filename, "is a directory");
+ if (st.st_size == 0)
+ return;
+
data = (const char*)mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (data == MAP_FAILED)
+ throw file_access_error{filename, strerror(errno)};
+
+ if (st.st_size > std::numeric_limits<int>::max())
+ throw runtime_error("file is too big");
}
MappedFile::~MappedFile()
{
if (fd != -1)
{
- munmap((void*)data, st.st_size);
+ if (data != nullptr)
+ munmap((void*)data, st.st_size);
close(fd);
}
}