diff --git a/reader/MarCCD.cpp b/reader/MarCCD.cpp index a5ee68d3a..96af47893 100644 --- a/reader/MarCCD.cpp +++ b/reader/MarCCD.cpp @@ -60,6 +60,15 @@ std::vector ReadPrefix(const std::string &path, size_t bytes) { std::ifstream f(path, std::ios::binary); if (!f) throw JFJochException(JFJochExceptionCategory::MockFileOpenError, "Cannot open " + path); + // Never allocate more than the file holds. One caller's count comes from the header-offset TIFF + // tag, which is a field of a file nobody has yet decided is ours - this runs on every input the + // program is given - and a foreign or corrupt TIFF can name four gigabytes there. Reading short + // is already the normal outcome (the caller checks the size it got back), so the clamp costs + // nothing. + f.seekg(0, std::ios::end); + const std::streamoff file_bytes = f.tellg(); + f.seekg(0, std::ios::beg); + bytes = std::min(bytes, file_bytes > 0 ? static_cast(file_bytes) : size_t(0)); std::vector out(bytes); f.read(reinterpret_cast(out.data()), static_cast(bytes)); out.resize(static_cast(f.gcount()));