Clamp the marCCD header probe to the size of the file
The header offset comes from TIFF tag 34710 unchecked and is handed to ReadPrefix, which allocates that many bytes before reading. This runs during format autodetection, on files nobody has said are marCCD, so a foreign or corrupt TIFF could have the program allocate ~4 GB for a probe. The probe now reads at most what the file holds; a short read was always the normal outcome and the caller already checks the size. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT
This commit is contained in:
@@ -60,6 +60,15 @@ std::vector<uint8_t> 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<size_t>(file_bytes) : size_t(0));
|
||||
std::vector<uint8_t> out(bytes);
|
||||
f.read(reinterpret_cast<char *>(out.data()), static_cast<std::streamsize>(bytes));
|
||||
out.resize(static_cast<size_t>(f.gcount()));
|
||||
|
||||
Reference in New Issue
Block a user