From 746919b3d25415025d7397b5afa51bf7e8e9c2e2 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 26 Sep 2026 18:49:54 -0500 Subject: [PATCH] fix: skip raw terrain chunk data with 64 bit relative seeks Each skip computed an absolute offset as a 32 bit tellg plus a size product in 32 bit math (colorMapSize * colorMapSize * 4 and friends), which wraps for large values and can seek backwards. The skips are now relative to the current position with the size promoted to std::streamoff first. Offsets are unchanged for every real terrain file, so this only removes the overflow the TODO asked about. Co-Authored-By: Claude Opus 5.5 --- dNavigation/dTerrain/RawChunk.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dNavigation/dTerrain/RawChunk.cpp b/dNavigation/dTerrain/RawChunk.cpp index df4950d4f..695740ff5 100644 --- a/dNavigation/dTerrain/RawChunk.cpp +++ b/dNavigation/dTerrain/RawChunk.cpp @@ -18,43 +18,43 @@ RawChunk::RawChunk(std::ifstream& stream) { // We can just skip the rest of the data so we can read the next chunks, we don't need anymore data - // Possible overflow here? TODO make reasonable upper bound or confirm big numbers arent necessary to have + // Skips are relative and done in 64 bit math so large sizes can't wrap around and seek backwards. uint32_t colorMapSize; BinaryIO::BinaryRead(stream, colorMapSize); - stream.seekg(static_cast(stream.tellg()) + (colorMapSize * colorMapSize * 4)); + stream.seekg(static_cast(colorMapSize) * colorMapSize * 4, std::ios::cur); uint32_t lightmapSize; BinaryIO::BinaryRead(stream, lightmapSize); - stream.seekg(static_cast(stream.tellg()) + (lightmapSize)); + stream.seekg(static_cast(lightmapSize), std::ios::cur); uint32_t colorMapSize2; BinaryIO::BinaryRead(stream, colorMapSize2); - stream.seekg(static_cast(stream.tellg()) + (colorMapSize2 * colorMapSize2 * 4)); + stream.seekg(static_cast(colorMapSize2) * colorMapSize2 * 4, std::ios::cur); uint8_t unknown; BinaryIO::BinaryRead(stream, unknown); uint32_t blendmapSize; BinaryIO::BinaryRead(stream, blendmapSize); - stream.seekg(static_cast(stream.tellg()) + (blendmapSize)); + stream.seekg(static_cast(blendmapSize), std::ios::cur); uint32_t pointSize; BinaryIO::BinaryRead(stream, pointSize); - stream.seekg(static_cast(stream.tellg()) + (pointSize * 9 * 4)); + stream.seekg(static_cast(pointSize) * 9 * 4, std::ios::cur); - stream.seekg(static_cast(stream.tellg()) + (colorMapSize * colorMapSize)); + stream.seekg(static_cast(colorMapSize) * colorMapSize, std::ios::cur); uint32_t endCounter; BinaryIO::BinaryRead(stream, endCounter); - stream.seekg(static_cast(stream.tellg()) + (endCounter * 2)); + stream.seekg(static_cast(endCounter) * 2, std::ios::cur); if (endCounter != 0) { - stream.seekg(static_cast(stream.tellg()) + (32)); + stream.seekg(32, std::ios::cur); for (int i = 0; i < 0x10; i++) { uint16_t finalCountdown; BinaryIO::BinaryRead(stream, finalCountdown); - stream.seekg(static_cast(stream.tellg()) + (finalCountdown * 2)); + stream.seekg(static_cast(finalCountdown) * 2, std::ios::cur); } }