aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0975-Validate-ResourceLocation-in-NBT-reading.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0975-Validate-ResourceLocation-in-NBT-reading.patch')
-rw-r--r--patches/server/0975-Validate-ResourceLocation-in-NBT-reading.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/patches/server/0975-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0975-Validate-ResourceLocation-in-NBT-reading.patch
new file mode 100644
index 0000000000..74748ab8d8
--- /dev/null
+++ b/patches/server/0975-Validate-ResourceLocation-in-NBT-reading.patch
@@ -0,0 +1,143 @@
+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 ba0726157417cdde1c9bca93a9e37e68d9b2286d..e3a3f19a6e63fd42e29c418e5a7439972484d492 100644
+--- a/src/main/java/net/minecraft/nbt/NbtUtils.java
++++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
+@@ -230,8 +230,10 @@ public final class NbtUtils {
+ if (!nbt.contains("Name", 8)) {
+ return Blocks.AIR.defaultBlockState();
+ } else {
+- ResourceLocation resourceLocation = new ResourceLocation(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 5f9dcab27a07969c93555ad0892683c62cbebc8c..a4d875df936b6de16f0233482b03af05b427a79f 100644
+--- a/src/main/java/net/minecraft/resources/ResourceLocation.java
++++ b/src/main/java/net/minecraft/resources/ResourceLocation.java
+@@ -31,6 +31,13 @@ public class ResourceLocation implements Comparable<ResourceLocation> {
+ private final String path;
+
+ protected ResourceLocation(String namespace, String path, @Nullable ResourceLocation.Dummy extraData) {
++ // 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/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
+index 8ba573bb4099ee5b27b61f333e72d794c48d5f29..69bdf3f2ee731e59e8d454816a9ca72cb49c0fe0 100644
+--- a/src/main/java/net/minecraft/world/entity/EntityType.java
++++ b/src/main/java/net/minecraft/world/entity/EntityType.java
+@@ -614,7 +614,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
+ }
+
+ public static Optional<EntityType<?>> by(CompoundTag nbt) {
+- return BuiltInRegistries.ENTITY_TYPE.getOptional(new ResourceLocation(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 e2e5ec647725f1f16067003ec773530d72fc5fcf..761c7136147a5c65f700daadfc370cbd13b0b455 100644
+--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
+@@ -879,12 +879,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 544e22f569d7ddeb1ba46a9ef7f4d4d6ca37c431..d2f5d959d3b67f7c20d0c0de462a18d667f3a84b 100644
+--- a/src/main/java/net/minecraft/world/entity/Mob.java
++++ b/src/main/java/net/minecraft/world/entity/Mob.java
+@@ -608,7 +608,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+
+ this.setLeftHanded(nbt.getBoolean("LeftHanded"));
+ if (nbt.contains("DeathLootTable", 8)) {
+- this.lootTable = new ResourceLocation(nbt.getString("DeathLootTable"));
++ this.lootTable = ResourceLocation.tryParse(nbt.getString("DeathLootTable")); // 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 c30f19162e33dbe8f018b7dc66210681b6027389..e8faca6e443239968f0111519f9e5cd018ed3297 100644
+--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
++++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+@@ -561,7 +561,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(new ResourceLocation(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
+ }
+
+ this.setShotFromCrossbow(nbt.getBoolean("ShotFromCrossbow"));
+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 7529751afa2932fd16bc4591189b0358268a7b14..e2e1c7a017e82dc7299e5cd1783818e4f0319c0b 100644
+--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
++++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
+@@ -67,7 +67,7 @@ public interface ContainerEntity extends Container, MenuProvider {
+ default void readChestVehicleSaveData(CompoundTag nbt) {
+ this.clearItemStacks();
+ if (nbt.contains("LootTable", 8)) {
+- this.setLootTable(new ResourceLocation(nbt.getString("LootTable")));
++ this.setLootTable(ResourceLocation.tryParse(nbt.getString("LootTable"))); // Paper - Validate ResourceLocation
+ this.setLootTableSeed(nbt.getLong("LootTableSeed"));
+ }
+
+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 d04fc84eef11adb5ea64077f48794b6ed7fb3ada..89d06253b00604114e543ebbe12a9993ae95dc41 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
+@@ -290,7 +290,12 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
+ while (iterator.hasNext()) {
+ String s = (String) iterator.next();
+
+- this.recipesUsed.put(new ResourceLocation(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 b5b1831631e233a96b6fd55972a8862b0f420da8..3f62e823bf9b5aa696e3c240613a0fb50340875e 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
+@@ -199,7 +199,7 @@ public class BrushableBlockEntity extends BlockEntity {
+
+ private boolean tryLoadLootTable(CompoundTag nbt) {
+ if (nbt.contains("LootTable", 8)) {
+- this.lootTable = new ResourceLocation(nbt.getString("LootTable"));
++ this.lootTable = ResourceLocation.tryParse(nbt.getString("LootTable")); // Paper - Validate ResourceLocation
+ this.lootTableSeed = nbt.getLong("LootTableSeed");
+ return true;
+ } else {