mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-15 08:17:13 +00:00
fix: limit the chunks and the inflated size of an sd0 buffer
An sd0 buffer could hold any number of chunks, and each chunk grew the inflated data by a full chunk whatever it held, so the data of a chunk that was not full was followed by a gap. A buffer now holds at most 4096 chunks and inflates to at most 64 MiB, and every chunk is inflated right after the one before it. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,11 @@ Sd0::Sd0(std::istream& buffer) {
|
||||
LOG("Failed to read chunk size from stream %lld %zu", buffer.tellg(), m_Chunks.size());
|
||||
break;
|
||||
}
|
||||
if (m_Chunks.size() >= MAX_CHUNKS) {
|
||||
LOG("More than %u chunks in an sd0 buffer, rejecting.", MAX_CHUNKS);
|
||||
m_Chunks.clear();
|
||||
break;
|
||||
}
|
||||
auto& chunk = m_Chunks.emplace_back();
|
||||
bool firstBuffer = m_Chunks.size() == 1;
|
||||
auto dataOffset = GetDataOffset(firstBuffer);
|
||||
@@ -155,7 +160,8 @@ std::string Sd0::GetAsStringUncompressed() const {
|
||||
break;
|
||||
}
|
||||
|
||||
auto oldSize = toReturn.size();
|
||||
// Each chunk is inflated right after the one before it
|
||||
const auto oldSize = toReturn.size();
|
||||
toReturn.resize(oldSize + MAX_UNCOMPRESSED_CHUNK_SIZE);
|
||||
int32_t error{};
|
||||
const auto uncompressedSize = ZCompression::Decompress(
|
||||
@@ -171,6 +177,14 @@ std::string Sd0::GetAsStringUncompressed() const {
|
||||
}
|
||||
|
||||
totalSize += uncompressedSize;
|
||||
toReturn.resize(totalSize);
|
||||
|
||||
if (totalSize > MAX_UNCOMPRESSED_SIZE) {
|
||||
LOG("An sd0 buffer inflates to more than %u bytes, aborting", MAX_UNCOMPRESSED_SIZE);
|
||||
toReturn = "";
|
||||
totalSize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
toReturn.resize(totalSize);
|
||||
|
||||
Reference in New Issue
Block a user