From ed13020cf3cb41d2a30d4b4f67c62195a02dc9cb Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 16:10:48 +0100 Subject: [PATCH] s integer overflow, unsafe cast --- Minecraft.Client/Level/ServerLevel.cpp | 6 ++--- .../Containers/MerchantRecipeList.cpp | 6 ++--- Minecraft.World/Entities/Entity.cpp | 24 ++++++++++--------- Minecraft.World/Level/RandomLevelSource.cpp | 4 ++-- .../Level/Storage/McRegionChunkStorage.cpp | 5 ++-- .../Sources/HellRandomLevelSource.cpp | 3 ++- .../Sources/TheEndLevelRandomLevelSource.cpp | 3 ++- 7 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index 6d56be34e..f4e5d5aeb 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -631,9 +631,9 @@ std::vector *ServerLevel::fetchTicksInChunk(LevelChunk *chunk, std::vector *results = new std::vector; ChunkPos *pos = chunk->getPos(); - int west = pos->x << 4; + int west = (unsigned) pos->x << 4; int east = west + 16; - int north = pos->z << 4; + int north =(unsigned) pos->z << 4; int south = north + 16; delete pos; @@ -1461,4 +1461,4 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFoun { chunkMap->flagEntitiesToBeRemoved(flags, removedFound); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Containers/MerchantRecipeList.cpp b/Minecraft.World/Containers/MerchantRecipeList.cpp index e8eb3ba35..f08225bbb 100644 --- a/Minecraft.World/Containers/MerchantRecipeList.cpp +++ b/Minecraft.World/Containers/MerchantRecipeList.cpp @@ -135,11 +135,11 @@ MerchantRecipeList *MerchantRecipeList::createFromStream(DataInputStream *stream void MerchantRecipeList::load(CompoundTag *tag) { - ListTag *list = (ListTag *) tag->getList(L"Recipes"); + ListTag *list = tag->getList(L"Recipes"); for (int i = 0; i < list->size(); i++) { - CompoundTag *recipeTag = list->get(i); + CompoundTag *recipeTag = (CompoundTag*) list->get(i); m_recipes.push_back(new MerchantRecipe(recipeTag)); } } @@ -192,4 +192,4 @@ size_t MerchantRecipeList::size() bool MerchantRecipeList::empty() { return m_recipes.empty(); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 9c88a00e2..b47749604 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -1342,13 +1342,15 @@ void Entity::saveWithoutId(CompoundTag *entityTag) void Entity::load(CompoundTag *tag) { - ListTag *pos = (ListTag *) tag->getList(L"Pos"); - ListTag *motion = (ListTag *) tag->getList(L"Motion"); - ListTag *rotation = (ListTag *) tag->getList(L"Rotation"); + // 4jcraft changed c style cast of templated class + // to getting the actual type and casting when needed + ListTag *pos = tag->getList(L"Pos"); + ListTag *motion = tag->getList(L"Motion"); + ListTag *rotation = tag->getList(L"Rotation"); - xd = motion->get(0)->data; - yd = motion->get(1)->data; - zd = motion->get(2)->data; + xd = ((DoubleTag*)motion->get(0))->data; + yd = ((DoubleTag*)motion->get(1))->data; + zd = ((DoubleTag*)motion->get(2))->data; if (abs(xd) > 10.0) { @@ -1363,12 +1365,12 @@ void Entity::load(CompoundTag *tag) zd = 0; } - xo = xOld = x = pos->get(0)->data; - yo = yOld = y = pos->get(1)->data; - zo = zOld = z = pos->get(2)->data; + xo = xOld = x = ((DoubleTag*)pos->get(0))->data; + yo = yOld = y = ((DoubleTag*)pos->get(1))->data; + zo = zOld = z = ((DoubleTag*)pos->get(2))->data; - yRotO = yRot = rotation->get(0)->data; - xRotO = xRot = rotation->get(1)->data; + yRotO = yRot = ((FloatTag*)rotation->get(0))->data; + xRotO = xRot = ((FloatTag*)rotation->get(1))->data; fallDistance = tag->getFloat(L"FallDistance"); onFire = tag->getShort(L"Fire"); diff --git a/Minecraft.World/Level/RandomLevelSource.cpp b/Minecraft.World/Level/RandomLevelSource.cpp index b18278516..0dad9dd00 100644 --- a/Minecraft.World/Level/RandomLevelSource.cpp +++ b/Minecraft.World/Level/RandomLevelSource.cpp @@ -654,8 +654,8 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - // 4jcraft added casts to u, holy moly, the getSeed is 64 bit and the result is 32... - pprandom->setSeed((((uint64_t)(int64_t)xt * (uint64_t)(int64_t)xScale) + ((uint64_t)(int64_t)zt * (uint64_t)(int64_t)zScale)) ^ level->getSeed()); + // 4jcraft added casts to a higher int and unsigned + pprandom->setSeed((((uint64_t)xt * (uint64_t)xScale) + ((uint64_t)zt * (uint64_t)zScale)) ^ level->getSeed()); bool hasVillage = false; diff --git a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp index e31fab3c5..a0c8c2d75 100644 --- a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp @@ -80,7 +80,7 @@ LevelChunk *McRegionChunkStorage::load(Level *level, int x, int z) { // 4jcraft fixed cast from int to int64 and taking the mask of the upper bits // and cast to unsigned - __int64 index = ((uint64_t)(uint32_t)(x) << 32) | (((uint64_t)(uint32_t)(z))); + uint64_t index = ((uint64_t)(uint32_t)(x) << 32) | (((uint64_t)(uint32_t)(z))); AUTO_VAR(it, m_entityData.find(index)); if(it != m_entityData.end()) @@ -237,7 +237,8 @@ void McRegionChunkStorage::saveEntities(Level *level, LevelChunk *levelChunk) { #ifdef SPLIT_SAVES PIXBeginNamedEvent(0,"Saving entities"); - __int64 index = ((__int64)(levelChunk->x) << 32) | (((__int64)(levelChunk->z))&0x00000000FFFFFFFF); + // 4j added cast to unsigned and changed index to u + uint64_t index = ((uint64_t)(uint32_t)(levelChunk->x) << 32) | (((uint64_t)(uint32_t)(levelChunk->z))); delete m_entityData[index].data; diff --git a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp index 4af91f84d..8b3864211 100644 --- a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp @@ -432,7 +432,8 @@ void HellRandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + // 4jcraft added casts to a higher int and unsigned + pprandom->setSeed((((uint64_t)xt * (uint64_t)xScale) + ((uint64_t)zt * (uint64_t)zScale)) ^ level->getSeed()); netherBridgeFeature->postProcess(level, pprandom, xt, zt); diff --git a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp index 7280ea617..5e095e4e7 100644 --- a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp @@ -375,7 +375,8 @@ void TheEndLevelRandomLevelSource::postProcess(ChunkSource *parent, int xt, int pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + // 4jcraft added cast to higher int and unsigned + pprandom->setSeed((((uint64_t)xt * xScale) + ((uint64_t)zt * zScale)) ^ level->getSeed()); Biome *biome = level->getBiome(xo + 16, zo + 16); biome->decorate(level, pprandom, xo, zo); // 4J - passing pprandom rather than level->random here to make this consistent with our parallel world generation