aboutsummaryrefslogtreecommitdiff
path: root/zencore/compactbinary.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-09-19 10:02:56 +0200
committerGitHub <[email protected]>2022-09-19 01:02:56 -0700
commit14fe7d17060b2e12203ed4b1fbfe44dd5aa606ec (patch)
treeeaab0f00aa2c4aeb88d9d96be91c7e7eb6d6f775 /zencore/compactbinary.cpp
parent0.1.6-pre8 (diff)
downloadzen-14fe7d17060b2e12203ed4b1fbfe44dd5aa606ec.tar.xz
zen-14fe7d17060b2e12203ed4b1fbfe44dd5aa606ec.zip
LoadCompactBinary gracefully handles read failures and sizes larger than the archive (#165)
* add failing test * CompactBinary: Fixed LoadCompactBinary to gracefully handle read failures and sizes larger than the archive From https://p4-swarm.epicgames.net/changes/21983905 * changelog
Diffstat (limited to 'zencore/compactbinary.cpp')
-rw-r--r--zencore/compactbinary.cpp52
1 files changed, 28 insertions, 24 deletions
diff --git a/zencore/compactbinary.cpp b/zencore/compactbinary.cpp
index 375a97fc5..0e4a46fa1 100644
--- a/zencore/compactbinary.cpp
+++ b/zencore/compactbinary.cpp
@@ -1355,39 +1355,42 @@ LoadCompactBinary(BinaryReader& Ar, BufferAllocator Allocator)
CbFieldType FieldType;
uint64_t FieldSize = 1;
- // Read in small increments until the total field size is known, to avoid reading too far.
- for (;;)
+ for (const int64_t StartPos = Ar.CurrentOffset(); FieldSize > 0;)
{
- const int32_t ReadSize = int32_t(FieldSize - HeaderBytes.size());
- const size_t ReadOffset = HeaderBytes.size();
+ // Read in small increments until the total field size is known, to avoid reading too far.
+ const int32_t ReadSize = int32_t(FieldSize - HeaderBytes.size());
+ if (Ar.CurrentOffset() + ReadSize > Ar.GetSize())
+ {
+ break;
+ }
+
+ const size_t ReadOffset = HeaderBytes.size();
HeaderBytes.resize(ReadOffset + ReadSize);
Ar.Read(HeaderBytes.data() + ReadOffset, ReadSize);
if (TryMeasureCompactBinary(MakeMemoryView(HeaderBytes), FieldType, FieldSize))
{
+ if (FieldSize <= uint64_t(Ar.Size() - StartPos))
+ {
+ UniqueBuffer Buffer = Allocator(FieldSize);
+ ZEN_ASSERT(Buffer.GetSize() == FieldSize);
+ MutableMemoryView View = Buffer.GetMutableView();
+ memcpy(View.GetData(), HeaderBytes.data(), HeaderBytes.size());
+ View.RightChopInline(HeaderBytes.size());
+ if (!View.IsEmpty())
+ {
+ // Read the remainder of the field.
+ Ar.Read(View.GetData(), View.GetSize());
+ }
+ if (ValidateCompactBinary(Buffer, CbValidateMode::Default) == CbValidateError::None)
+ {
+ return CbField(SharedBuffer(std::move(Buffer)));
+ }
+ }
break;
}
- if (FieldSize == 0)
- {
- return CbField();
- }
}
-
- // Allocate the buffer, copy the header, and read the remainder of the field.
- UniqueBuffer Buffer = Allocator(FieldSize);
- ZEN_ASSERT(Buffer.GetSize() == FieldSize);
- MutableMemoryView View = Buffer.GetMutableView();
- memcpy(View.GetData(), HeaderBytes.data(), HeaderBytes.size());
- View.RightChopInline(HeaderBytes.size());
- if (!View.IsEmpty())
- {
- Ar.Read(View.GetData(), View.GetSize());
- }
- if (ValidateCompactBinary(Buffer, CbValidateMode::Default) != CbValidateError::None)
- {
- return CbField();
- }
- return CbField(SharedBuffer(std::move(Buffer)));
+ return CbField();
}
CbObject
@@ -2290,6 +2293,7 @@ TEST_CASE("json.uson")
CHECK(Cb["value"sv].AsHash() == Hash);
}
}
+
#endif
} // namespace zen