From 0e4db91666f72bc4fd43410a432c816d493e403c Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 15 May 2026 10:29:04 +0300 Subject: [PATCH] Add hard limit 10MB to reading non data files from zip file * check if uncompressed data does not exceed given size IB-8935 Signed-off-by: Raul Metsma --- src/DataFile.cpp | 4 +++- src/util/ZipSerialize.h | 13 +++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/DataFile.cpp b/src/DataFile.cpp index 2aafd1a83..a023f0056 100644 --- a/src/DataFile.cpp +++ b/src/DataFile.cpp @@ -113,13 +113,15 @@ DataFilePrivate::DataFilePrivate(const ZipSerialize &z, string filename, string for(size_t size = 0, currentStreamSize = 0; (size = r(buf.data(), buf.size())) > 0; currentStreamSize += size) { + if(currentStreamSize + size > r.size) + THROW("ZIP entry actual size exceeds uncompressed_size %lu", r.size); if(!fs->write(buf.data(), size)) THROW("Failed to write '%s' data to stream. Stream size: %d", m_filename.c_str(), currentStreamSize); } m_is = std::move(fs); } else - m_is = make_unique(r.operator string()); + m_is = make_unique(r(MAX_MEM_FILE)); } DataFilePrivate::~DataFilePrivate() noexcept = default; diff --git a/src/util/ZipSerialize.h b/src/util/ZipSerialize.h index aad8e743c..75e5d5c05 100644 --- a/src/util/ZipSerialize.h +++ b/src/util/ZipSerialize.h @@ -20,6 +20,7 @@ #pragma once #include "Exports.h" +#include "log.h" #include #include @@ -34,14 +35,22 @@ class ZipSerialize { public: struct Read { + static constexpr size_t maxSize = 10UL*1024*1024; size_t operator ()(void *data, size_t size) const; - template - constexpr operator T() const + template + T operator ()(size_t maxAlloc = maxSize) const { + if(size > maxAlloc) + THROW("ZIP entry uncompressed size %zu exceeds limit", size); T t(size, 0); t.resize(operator ()(t.data(), t.size())); + char extra{}; + if(operator ()(&extra, 1) > 0) + THROW("ZIP entry actual size exceeds uncompressed_size %zu", size); return t; } + template + constexpr operator T() const { return operator()(); } std::unique_ptr d; size_t size; };