diff --git a/dZoneManager/Raw.cpp b/dZoneManager/Raw.cpp index f74b2c6a..b9f2ae01 100644 --- a/dZoneManager/Raw.cpp +++ b/dZoneManager/Raw.cpp @@ -6,6 +6,11 @@ #include #include +namespace { +constexpr uint32_t kMaxResolution = 4096; +constexpr size_t kMaxBlobBytes = 64ULL * 1024 * 1024; // 64 MiB +} // namespace + namespace Raw { /** @@ -106,9 +111,17 @@ namespace Raw { chunk.colorMapResolution = chunk.width; // Default to chunk width for older versions } - uint32_t colorMapPixelCount = chunk.colorMapResolution * chunk.colorMapResolution * 4; // RGBA + if (chunk.colorMapResolution > kMaxResolution) { + LOG("Chunk colorMapResolution %u exceeds maximum %u", chunk.colorMapResolution, kMaxResolution); + return false; + } + const size_t colorMapPixelCount = static_cast(chunk.colorMapResolution) * chunk.colorMapResolution * 4; // RGBA + if (colorMapPixelCount > kMaxBlobBytes) { + LOG("Chunk colorMap size %zu exceeds maximum %zu bytes", colorMapPixelCount, kMaxBlobBytes); + return false; + } chunk.colorMap.resize(colorMapPixelCount); - stream.read(reinterpret_cast(chunk.colorMap.data()), colorMapPixelCount); + stream.read(reinterpret_cast(chunk.colorMap.data()), static_cast(colorMapPixelCount)); if (stream.fail()) { return false; @@ -117,8 +130,12 @@ namespace Raw { uint32_t lightMapSize; BinaryIO::BinaryRead(stream, lightMapSize); + if (lightMapSize > kMaxBlobBytes) { + LOG("Chunk lightMap size %u exceeds maximum %zu bytes", lightMapSize, kMaxBlobBytes); + return false; + } chunk.lightMap.resize(lightMapSize); - stream.read(reinterpret_cast(chunk.lightMap.data()), lightMapSize); + stream.read(reinterpret_cast(chunk.lightMap.data()), static_cast(lightMapSize)); if (stream.fail()) { return false; @@ -131,9 +148,17 @@ namespace Raw { chunk.textureMapResolution = chunk.width; // Default to chunk width for older versions } - uint32_t textureMapPixelCount = chunk.textureMapResolution * chunk.textureMapResolution * 4; + if (chunk.textureMapResolution > kMaxResolution) { + LOG("Chunk textureMapResolution %u exceeds maximum %u", chunk.textureMapResolution, kMaxResolution); + return false; + } + const size_t textureMapPixelCount = static_cast(chunk.textureMapResolution) * chunk.textureMapResolution * 4; + if (textureMapPixelCount > kMaxBlobBytes) { + LOG("Chunk textureMap size %zu exceeds maximum %zu bytes", textureMapPixelCount, kMaxBlobBytes); + return false; + } chunk.textureMap.resize(textureMapPixelCount); - stream.read(reinterpret_cast(chunk.textureMap.data()), textureMapPixelCount); + stream.read(reinterpret_cast(chunk.textureMap.data()), static_cast(textureMapPixelCount)); if (stream.fail()) { return false; @@ -146,8 +171,12 @@ namespace Raw { uint32_t blendMapDDSSize; BinaryIO::BinaryRead(stream, blendMapDDSSize); + if (blendMapDDSSize > kMaxBlobBytes) { + LOG("Chunk blendMap size %u exceeds maximum %zu bytes", blendMapDDSSize, kMaxBlobBytes); + return false; + } chunk.blendMap.resize(blendMapDDSSize); - stream.read(reinterpret_cast(chunk.blendMap.data()), blendMapDDSSize); + stream.read(reinterpret_cast(chunk.blendMap.data()), static_cast(blendMapDDSSize)); if (stream.fail()) { return false; @@ -170,10 +199,14 @@ namespace Raw { // Scene map (version 32+ only) if (version >= 32) { - uint32_t sceneMapSize = chunk.colorMapResolution * chunk.colorMapResolution; + const size_t sceneMapSize = static_cast(chunk.colorMapResolution) * chunk.colorMapResolution; + if (sceneMapSize > kMaxBlobBytes) { + LOG("Chunk sceneMap size %zu exceeds maximum %zu bytes", sceneMapSize, kMaxBlobBytes); + return false; + } chunk.sceneMap.resize(sceneMapSize); - stream.read(reinterpret_cast(chunk.sceneMap.data()), sceneMapSize); + stream.read(reinterpret_cast(chunk.sceneMap.data()), static_cast(sceneMapSize)); if (stream.fail()) { return false; diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index f4df5ccb..54905de2 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -406,7 +406,7 @@ void dZoneManager::BuildSceneGraph() { } // Scene 0 (global scene) is always loaded and adjacent to all other scenes - LWOSCENEID globalScene = LWOSCENEID(m_ZoneID.GetMapID(), 0); + LWOSCENEID globalScene = LWOSCENEID(0, 0); for (auto& [sceneID, adjacentScenes] : m_SceneAdjacencyList) { if (sceneID != globalScene) { // Add global scene to this scene's adjacency list if not already present