mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #14224 from janisozaur/sawyerchunktests
Extend tests for SawyerCoding
This commit is contained in:
commit
6df6200a0d
|
@ -27,19 +27,6 @@ constexpr const char* EXCEPTION_MSG_DESTINATION_TOO_SMALL = "Chunk data larger t
|
|||
constexpr const char* EXCEPTION_MSG_INVALID_CHUNK_ENCODING = "Invalid chunk encoding.";
|
||||
constexpr const char* EXCEPTION_MSG_ZERO_SIZED_CHUNK = "Encountered zero-sized chunk.";
|
||||
|
||||
class SawyerChunkException : public IOException
|
||||
{
|
||||
public:
|
||||
explicit SawyerChunkException(const char* message)
|
||||
: IOException(message)
|
||||
{
|
||||
}
|
||||
explicit SawyerChunkException(const std::string& message)
|
||||
: IOException(message)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
SawyerChunkReader::SawyerChunkReader(OpenRCT2::IStream* stream)
|
||||
: _stream(stream)
|
||||
{
|
||||
|
@ -84,13 +71,22 @@ std::shared_ptr<SawyerChunk> SawyerChunkReader::ReadChunk()
|
|||
}
|
||||
|
||||
auto buffer = static_cast<uint8_t*>(AllocateLargeTempBuffer());
|
||||
size_t uncompressedLength = DecodeChunk(buffer, MAX_UNCOMPRESSED_CHUNK_SIZE, compressedData.get(), header);
|
||||
if (uncompressedLength == 0)
|
||||
try
|
||||
{
|
||||
throw SawyerChunkException(EXCEPTION_MSG_ZERO_SIZED_CHUNK);
|
||||
size_t uncompressedLength = DecodeChunk(buffer, MAX_UNCOMPRESSED_CHUNK_SIZE, compressedData.get(), header);
|
||||
if (uncompressedLength == 0)
|
||||
{
|
||||
throw SawyerChunkException(EXCEPTION_MSG_ZERO_SIZED_CHUNK);
|
||||
}
|
||||
buffer = static_cast<uint8_t*>(FinaliseLargeTempBuffer(buffer, uncompressedLength));
|
||||
return std::make_shared<SawyerChunk>(
|
||||
static_cast<SAWYER_ENCODING>(header.encoding), buffer, uncompressedLength);
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
FreeLargeTempBuffer(buffer);
|
||||
throw;
|
||||
}
|
||||
buffer = static_cast<uint8_t*>(FinaliseLargeTempBuffer(buffer, uncompressedLength));
|
||||
return std::make_shared<SawyerChunk>(static_cast<SAWYER_ENCODING>(header.encoding), buffer, uncompressedLength);
|
||||
}
|
||||
default:
|
||||
throw SawyerChunkException(EXCEPTION_MSG_INVALID_CHUNK_ENCODING);
|
||||
|
@ -192,10 +188,10 @@ size_t SawyerChunkReader::DecodeChunk(void* dst, size_t dstCapacity, const void*
|
|||
|
||||
size_t SawyerChunkReader::DecodeChunkRLERepeat(void* dst, size_t dstCapacity, const void* src, size_t srcLength)
|
||||
{
|
||||
auto immBuffer = AllocateLargeTempBuffer();
|
||||
auto immLength = DecodeChunkRLE(immBuffer, MAX_UNCOMPRESSED_CHUNK_SIZE, src, srcLength);
|
||||
auto size = DecodeChunkRepeat(dst, dstCapacity, immBuffer, immLength);
|
||||
FreeLargeTempBuffer(immBuffer);
|
||||
auto immBuffer = std::unique_ptr<uint8_t, decltype(&FreeLargeTempBuffer)>(
|
||||
static_cast<uint8_t*>(AllocateLargeTempBuffer()), &FreeLargeTempBuffer);
|
||||
auto immLength = DecodeChunkRLE(immBuffer.get(), MAX_UNCOMPRESSED_CHUNK_SIZE, src, srcLength);
|
||||
auto size = DecodeChunkRepeat(dst, dstCapacity, immBuffer.get(), immLength);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -267,6 +263,15 @@ size_t SawyerChunkReader::DecodeChunkRepeat(void* dst, size_t dstCapacity, const
|
|||
{
|
||||
throw SawyerChunkException(EXCEPTION_MSG_DESTINATION_TOO_SMALL);
|
||||
}
|
||||
if (copySrc < dst)
|
||||
{
|
||||
throw SawyerChunkException(EXCEPTION_MSG_CORRUPT_RLE);
|
||||
}
|
||||
if ((copySrc < (dst8 + count) && copySrc >= dst8)
|
||||
|| ((copySrc + count) <= (dst8 + count) && (copySrc + count) > dst8))
|
||||
{
|
||||
throw SawyerChunkException(EXCEPTION_MSG_CORRUPT_RLE);
|
||||
}
|
||||
|
||||
std::memcpy(dst8, copySrc, count);
|
||||
dst8 += count;
|
||||
|
|
|
@ -10,11 +10,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/IStream.hpp"
|
||||
#include "../util/SawyerCoding.h"
|
||||
#include "SawyerChunk.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class SawyerChunkException : public IOException
|
||||
{
|
||||
public:
|
||||
explicit SawyerChunkException(const char* message)
|
||||
: IOException(message)
|
||||
{
|
||||
}
|
||||
explicit SawyerChunkException(const std::string& message)
|
||||
: IOException(message)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
struct IStream;
|
||||
|
|
|
@ -22,6 +22,14 @@ protected:
|
|||
static const uint8_t rledata[1038];
|
||||
static const uint8_t rlecompresseddata[1949];
|
||||
static const uint8_t rotatedata[1029];
|
||||
static const uint8_t invalid1[11];
|
||||
static const uint8_t invalid2[11];
|
||||
static const uint8_t invalid3[14];
|
||||
static const uint8_t invalid4[7];
|
||||
static const uint8_t invalid5[8];
|
||||
static const uint8_t invalid6[7];
|
||||
static const uint8_t invalid7[6];
|
||||
static const uint8_t empty[1];
|
||||
|
||||
void test_encode_decode(uint8_t encoding_type)
|
||||
{
|
||||
|
@ -106,6 +114,62 @@ TEST_F(SawyerCodingTest, decode_chunk_rotate)
|
|||
test_decode(rotatedata, sizeof(rotatedata));
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid1)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid1, sizeof(invalid1));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid2)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid2, sizeof(invalid2));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid3)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid3, sizeof(invalid3));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid4)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid4, sizeof(invalid4));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid5)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid5, sizeof(invalid5));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid6)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid6, sizeof(invalid6));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, invalid7)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(invalid7, sizeof(invalid7));
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), SawyerChunkException);
|
||||
}
|
||||
|
||||
TEST_F(SawyerCodingTest, empty)
|
||||
{
|
||||
OpenRCT2::MemoryStream ms(empty, 0);
|
||||
SawyerChunkReader reader(&ms);
|
||||
EXPECT_THROW(reader.ReadChunk(), IOException);
|
||||
}
|
||||
|
||||
// 1024 bytes of random data
|
||||
// use `dd if=/dev/urandom bs=1024 count=1 | xxd -i` to get your own
|
||||
const uint8_t SawyerCodingTest::randomdata[] = {
|
||||
|
@ -430,3 +494,21 @@ const uint8_t SawyerCodingTest::rotatedata[] = {
|
|||
0xee, 0x6d, 0x4b, 0x24, 0x20, 0x9c, 0x83, 0xdb, 0xce, 0x18, 0xb8, 0xa3, 0x8a, 0x52, 0xda, 0x1a, 0x33, 0xe4, 0xc5, 0x07,
|
||||
0x40, 0x7d, 0xf4, 0xfa, 0x2f, 0x6b, 0x93, 0x44, 0x5e,
|
||||
};
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid1[] = { 0x02, 0x04, 0x00, 0x00, 0x00, 0xd4, 0xff, 0xce, 0xcf, 0x2e, 0x00 };
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid2[] = { 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x3f, 0x01, 0x00 };
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid3[] = { 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x73 };
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid4[] = { 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid5[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00 };
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid6[] = { 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x7f };
|
||||
|
||||
const uint8_t SawyerCodingTest::invalid7[] = { 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
// This needs to be non-empty to satisfy MSVC. We still pass zero as length.
|
||||
const uint8_t SawyerCodingTest::empty[] = { 0x00 };
|
||||
|
|
Loading…
Reference in New Issue