1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-11-30 13:34:33 +00:00

Check if nif stream has requested amount of data

Memory allocation with initialization may take significat amount of time
if meta information does not match actual content.
This commit is contained in:
elsid 2025-09-19 19:26:22 +02:00
parent 1ae0aadfed
commit e882c1c722
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
2 changed files with 18 additions and 0 deletions

View file

@ -57,6 +57,7 @@ namespace Nif
std::string NIFStream::getSizedString(size_t length) std::string NIFStream::getSizedString(size_t length)
{ {
checkStreamSize(length);
std::string str(length, '\0'); std::string str(length, '\0');
mStream->read(str.data(), length); mStream->read(str.data(), length);
if (mStream->fail()) if (mStream->fail())
@ -90,6 +91,7 @@ namespace Nif
std::string NIFStream::getStringPalette() std::string NIFStream::getStringPalette()
{ {
size_t size = get<uint32_t>(); size_t size = get<uint32_t>();
checkStreamSize(size);
std::string str(size, '\0'); std::string str(size, '\0');
mStream->read(str.data(), size); mStream->read(str.data(), size);
if (mStream->fail()) if (mStream->fail())
@ -235,6 +237,7 @@ namespace Nif
{ {
if (getVersion() < generateVersion(4, 1, 0, 0)) if (getVersion() < generateVersion(4, 1, 0, 0))
{ {
checkStreamSize(size * sizeof(int32_t));
std::vector<int32_t> buf(size); std::vector<int32_t> buf(size);
read(buf.data(), size); read(buf.data(), size);
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
@ -242,6 +245,7 @@ namespace Nif
} }
else else
{ {
checkStreamSize(size * sizeof(int8_t));
std::vector<int8_t> buf(size); std::vector<int8_t> buf(size);
read(buf.data(), size); read(buf.data(), size);
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
@ -264,4 +268,9 @@ namespace Nif
} }
} }
void NIFStream::checkStreamSize(std::size_t size)
{
if (size > mStreamSize)
throw std::runtime_error(std::format("Trying to read more than stream size: {} max={}", size, mStreamSize));
}
} }

View file

@ -16,6 +16,7 @@
#include <vector> #include <vector>
#include <components/files/istreamptr.hpp> #include <components/files/istreamptr.hpp>
#include <components/files/utils.hpp>
#include <components/misc/endianness.hpp> #include <components/misc/endianness.hpp>
#include <components/misc/float16.hpp> #include <components/misc/float16.hpp>
@ -78,6 +79,7 @@ namespace Nif
Files::IStreamPtr mStream; Files::IStreamPtr mStream;
const ToUTF8::StatelessUtf8Encoder* mEncoder; const ToUTF8::StatelessUtf8Encoder* mEncoder;
std::string mBuffer; std::string mBuffer;
std::size_t mStreamSize;
public: public:
explicit NIFStream( explicit NIFStream(
@ -85,6 +87,7 @@ namespace Nif
: mReader(reader) : mReader(reader)
, mStream(std::move(stream)) , mStream(std::move(stream))
, mEncoder(encoder) , mEncoder(encoder)
, mStreamSize(static_cast<std::size_t>(Files::getStreamSizeLeft(*mStream)))
{ {
} }
@ -129,6 +132,9 @@ namespace Nif
{ {
if (size == 0) if (size == 0)
return; return;
checkStreamSize(size * sizeof(T));
vec.resize(size); vec.resize(size);
read(vec.data(), size); read(vec.data(), size);
} }
@ -159,6 +165,9 @@ namespace Nif
/// Read a sequence of null-terminated strings /// Read a sequence of null-terminated strings
std::string getStringPalette(); std::string getStringPalette();
private:
void checkStreamSize(std::size_t size);
}; };
template <> template <>