diff options
Diffstat (limited to 'patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch')
-rw-r--r-- | patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch new file mode 100644 index 0000000000..5531d9ffc8 --- /dev/null +++ b/patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch @@ -0,0 +1,155 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Nassim Jahnke <[email protected]> +Date: Thu, 4 Jan 2024 13:49:14 +0100 +Subject: [PATCH] Validate ResourceLocation in NBT reading + + +diff --git a/src/main/java/net/minecraft/nbt/NbtUtils.java b/src/main/java/net/minecraft/nbt/NbtUtils.java +index 4929bac8e476664086470f078efce6c0a6164413..f88dd37783b3c155c23b547c360b8d3c16e030c0 100644 +--- a/src/main/java/net/minecraft/nbt/NbtUtils.java ++++ b/src/main/java/net/minecraft/nbt/NbtUtils.java +@@ -149,8 +149,10 @@ public final class NbtUtils { + if (!nbt.contains("Name", 8)) { + return Blocks.AIR.defaultBlockState(); + } else { +- ResourceLocation resourceLocation = ResourceLocation.parse(nbt.getString("Name")); +- Optional<? extends Holder<Block>> optional = blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation)); ++ // Paper start - Validate resource location ++ ResourceLocation resourceLocation = ResourceLocation.tryParse(nbt.getString("Name")); ++ Optional<? extends Holder<Block>> optional = resourceLocation != null ? blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation)) : Optional.empty(); ++ // Paper end - Validate resource location + if (optional.isEmpty()) { + return Blocks.AIR.defaultBlockState(); + } else { +diff --git a/src/main/java/net/minecraft/resources/ResourceLocation.java b/src/main/java/net/minecraft/resources/ResourceLocation.java +index 87afe84791af2d5e9f869cd4c09eed4bb5fee75b..1967c43ee3a12e63365cc40ee6565307e2fd73cf 100644 +--- a/src/main/java/net/minecraft/resources/ResourceLocation.java ++++ b/src/main/java/net/minecraft/resources/ResourceLocation.java +@@ -41,6 +41,13 @@ public final class ResourceLocation implements Comparable<ResourceLocation> { + + assert isValidPath(path); + ++ // Paper start - Validate ResourceLocation ++ // Check for the max network string length (capped at Short.MAX_VALUE) as well as the max bytes of a StringTag (length written as an unsigned short) ++ final String resourceLocation = namespace + ":" + path; ++ if (resourceLocation.length() > Short.MAX_VALUE || io.netty.buffer.ByteBufUtil.utf8MaxBytes(resourceLocation) > 2 * Short.MAX_VALUE + 1) { ++ throw new ResourceLocationException("Resource location too long: " + resourceLocation); ++ } ++ // Paper end - Validate ResourceLocation + this.namespace = namespace; + this.path = path; + } +diff --git a/src/main/java/net/minecraft/world/RandomizableContainer.java b/src/main/java/net/minecraft/world/RandomizableContainer.java +index 597cd5dbb4bb415a9b4d874c1c5dd621be1d6fc8..a9a80f8bc4a6f250fe3c20482c395058f024fabd 100644 +--- a/src/main/java/net/minecraft/world/RandomizableContainer.java ++++ b/src/main/java/net/minecraft/world/RandomizableContainer.java +@@ -50,7 +50,7 @@ public interface RandomizableContainer extends Container { + + default boolean tryLoadLootTable(CompoundTag nbt) { + if (nbt.contains("LootTable", 8)) { +- this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); ++ this.setLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation + if (this.lootableData() != null && this.getLootTable() != null) this.lootableData().loadNbt(nbt); // Paper - LootTable API + if (nbt.contains("LootTableSeed", 4)) { + this.setLootTableSeed(nbt.getLong("LootTableSeed")); +diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java +index b98f9246b60daf31460f41ce214dfa7c011f5684..842b0cec0397d7ae5166617627340ffac0e35db1 100644 +--- a/src/main/java/net/minecraft/world/entity/EntityType.java ++++ b/src/main/java/net/minecraft/world/entity/EntityType.java +@@ -623,7 +623,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT + } + + public static Optional<EntityType<?>> by(CompoundTag nbt) { +- return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(nbt.getString("id"))); ++ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(nbt.getString("id"))); // Paper - Validate ResourceLocation + } + + @Nullable +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index ff16c7196b146388c526e3100e561be771ca8a91..cbf076c5fa69d32ad3c8ea759cd9d405b60f8663 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -887,11 +887,13 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (nbt.contains("SleepingX", 99) && nbt.contains("SleepingY", 99) && nbt.contains("SleepingZ", 99)) { + BlockPos blockposition = new BlockPos(nbt.getInt("SleepingX"), nbt.getInt("SleepingY"), nbt.getInt("SleepingZ")); + ++ if (this.position().distanceToSqr(blockposition.getX(), blockposition.getY(), blockposition.getZ()) < 16 * 16) { // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong + this.setSleepingPos(blockposition); + this.entityData.set(LivingEntity.DATA_POSE, Pose.SLEEPING); + if (!this.firstTick) { + this.setPosToBed(blockposition); + } ++ } // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong + } + + if (nbt.contains("Brain", 10)) { +diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java +index 56873752ae1ae0d2a36cb171d2de6884e15c01a5..5bac748649f43d74b13e7c0b4d355e67654ad59e 100644 +--- a/src/main/java/net/minecraft/world/entity/Mob.java ++++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -605,7 +605,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + this.leashData = this.readLeashData(nbt); + this.setLeftHanded(nbt.getBoolean("LeftHanded")); + if (nbt.contains("DeathLootTable", 8)) { +- this.lootTable = ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("DeathLootTable"))); ++ this.lootTable = net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("DeathLootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl)); // Paper - Validate ResourceLocation + this.lootTableSeed = nbt.getLong("DeathLootTableSeed"); + } + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +index 10d30304c8c89b1f2a55be8529035311d1424e44..ddf47dab1ab92c45e3eea09239d418a9798ed59e 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +@@ -649,7 +649,7 @@ public abstract class AbstractArrow extends Projectile { + this.setCritArrow(nbt.getBoolean("crit")); + this.setPierceLevel(nbt.getByte("PierceLevel")); + if (nbt.contains("SoundEvent", 8)) { +- this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(ResourceLocation.parse(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent()); ++ this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(ResourceLocation.tryParse(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent()); // Paper - Validate resource location + } + + if (nbt.contains("item", 10)) { +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +index ccc7367ab2740bea0f2b907223a0920b11665092..845eff7401b811c179dc9dee70eca0d724be5c80 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +@@ -73,7 +73,7 @@ public interface ContainerEntity extends Container, MenuProvider { + default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registriesLookup) { + this.clearItemStacks(); + if (nbt.contains("LootTable", 8)) { +- this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); ++ this.setLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation + // Paper start - LootTable API + if (this.getLootTable() != null) { + this.lootableData().loadNbt(nbt); +diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +index 65ab9b22f724877b68f4f25aad2831e2cb080b19..730aca233f6e7564d4cb85b5b628d23c4f01d2f4 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +@@ -295,7 +295,12 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + while (iterator.hasNext()) { + String s = (String) iterator.next(); + +- this.recipesUsed.put(ResourceLocation.parse(s), nbttagcompound1.getInt(s)); ++ // Paper start - Validate ResourceLocation ++ final ResourceLocation resourceLocation = ResourceLocation.tryParse(s); ++ if (resourceLocation != null) { ++ this.recipesUsed.put(resourceLocation, nbttagcompound1.getInt(s)); ++ } ++ // Paper end - Validate ResourceLocation + } + + // Paper start - cook speed multiplier API +diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java +index 32de29c385c784ab87e29b2e072f3992386cd775..dc02a3d84b397f634f77f4df9c06e245cc4dcb75 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java +@@ -202,7 +202,7 @@ public class BrushableBlockEntity extends BlockEntity { + + private boolean tryLoadLootTable(CompoundTag nbt) { + if (nbt.contains("LootTable", 8)) { +- this.lootTable = ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable"))); ++ this.lootTable = net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl)); // Paper - Validate ResourceLocation + this.lootTableSeed = nbt.getLong("LootTableSeed"); + return true; + } else { |