PaperMC/patches/server/0941-Validate-ResourceLocation-in-NBT-reading.patch

157 lines
11 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
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
2024-04-25 01:25:57 +02:00
index 1d7c20fe14882fdeddf315a8923669e3385652f5..f88dd37783b3c155c23b547c360b8d3c16e030c0 100644
--- a/src/main/java/net/minecraft/nbt/NbtUtils.java
+++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
2024-04-25 01:25:57 +02:00
@@ -149,8 +149,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
2024-04-25 01:25:57 +02:00
index d93b623ce973b63d4f3a77bfe459f51af7cb3c1c..2c4553312f2f37f8613ac813708b4b95f9675e9f 100644
--- a/src/main/java/net/minecraft/resources/ResourceLocation.java
+++ b/src/main/java/net/minecraft/resources/ResourceLocation.java
2024-04-25 01:25:57 +02:00
@@ -37,6 +37,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/RandomizableContainer.java b/src/main/java/net/minecraft/world/RandomizableContainer.java
index 68fadc351464dde459eb4cc86660cf9add40d04e..feb35fba0c56445ee910dbe1af9b36f21b4ec480 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, new ResourceLocation(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
Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 69fa4695 Add some missing deprecation annotations f850da2e Update Maven plugins/versions 8d8400db Use regular compiler seeing as ECJ doesn't support Java 21 JRE c29e1688 Revert "BUILDTOOLS-676: Downgrade Maven compiler version" 07bce714 SPIGOT-7355: More field renames and fixes 6a8ea764 Fix bad merge in penultimate commit 50a7920c Fix imports in previous commit 83640dd1 PR-995: Add required feature to MinecraftExperimental for easy lookups fc1f96cf BUILDTOOLS-676: Downgrade Maven compiler version CraftBukkit Changes: 90f1059ba Fix item placement 661afb43c SPIGOT-7633: Clearer error message for missing particle data 807b465b3 SPIGOT-7634: Armadillo updates infrequently 590cf09a8 Fix unit tests always seeing Mojang server as unavailable 7c7ac5eb2 SPIGOT-7636: Fix clearing ItemMeta 4a72905cf SPIGOT-7635: Fix Player#transfer and cookie methods ebb50e136 Fix incorrect Vault implementation b33fed8b7 Update Maven plugins/versions 6f00f0608 SPIGOT-7632: Control middle clicking chest does not copy contents db821f405 Use regular compiler seeing as ECJ doesn't support Java 21 JRE 8a2976737 Revert "BUILDTOOLS-676: Downgrade Maven compiler version" 0297f87bb SPIGOT-7355: More field renames and fixes 2d03bdf6a SPIGOT-7629: Fix loading banner patterns e77951fac Fix equality of deserialized display names c66f3e4fd SPIGOT-7631: Fix deserialisation of BlockStateMeta 9c2c7be8d SPIGOT-7630: Fix crash saving unticked leashed entities 8c1e7c841 PR-1384: Disable certain PlayerProfile tests, if Mojang's services or internet are not available ced93d572 SPIGOT-7626: sendSignChange() has no effect c77362cae SPIGOT-7625: ItemStack with lore cannot be serialized in 1.20.5 ff2004387 SPIGOT-7620: Fix server crash when hoppers transfer items to double chests 8b4abeb03 BUILDTOOLS-676: Downgrade Maven compiler version
2024-04-25 23:21:18 +02:00
index 8c7cc9c5af0b8d8bef9b6e2d3d3e723cd76f3212..56b51096ca4147363a843accf6ef2510f05e8f1a 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
2024-04-25 01:25:57 +02:00
@@ -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(new ResourceLocation(nbt.getString("id")));
+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(nbt.getString("id"))); // Paper - Validate ResourceLocation
}
@Nullable
2024-02-01 10:53:15 +01:00
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index c256b4307e896b3e9f0a399a93db761a8c5c593f..5eda2e858b309d2be704db1015c9c114ed9e63a9 100644
2024-02-01 10:53:15 +01:00
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
2024-04-25 01:25:57 +02:00
@@ -911,12 +911,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
2024-02-01 10:53:15 +01:00
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 7a2fefda293d72d665fee71ef29eea6bad3c0861..f6008004c00d45e5fb5b0b2133011e4d20d7a1ff 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 69fa4695 Add some missing deprecation annotations f850da2e Update Maven plugins/versions 8d8400db Use regular compiler seeing as ECJ doesn't support Java 21 JRE c29e1688 Revert "BUILDTOOLS-676: Downgrade Maven compiler version" 07bce714 SPIGOT-7355: More field renames and fixes 6a8ea764 Fix bad merge in penultimate commit 50a7920c Fix imports in previous commit 83640dd1 PR-995: Add required feature to MinecraftExperimental for easy lookups fc1f96cf BUILDTOOLS-676: Downgrade Maven compiler version CraftBukkit Changes: 90f1059ba Fix item placement 661afb43c SPIGOT-7633: Clearer error message for missing particle data 807b465b3 SPIGOT-7634: Armadillo updates infrequently 590cf09a8 Fix unit tests always seeing Mojang server as unavailable 7c7ac5eb2 SPIGOT-7636: Fix clearing ItemMeta 4a72905cf SPIGOT-7635: Fix Player#transfer and cookie methods ebb50e136 Fix incorrect Vault implementation b33fed8b7 Update Maven plugins/versions 6f00f0608 SPIGOT-7632: Control middle clicking chest does not copy contents db821f405 Use regular compiler seeing as ECJ doesn't support Java 21 JRE 8a2976737 Revert "BUILDTOOLS-676: Downgrade Maven compiler version" 0297f87bb SPIGOT-7355: More field renames and fixes 2d03bdf6a SPIGOT-7629: Fix loading banner patterns e77951fac Fix equality of deserialized display names c66f3e4fd SPIGOT-7631: Fix deserialisation of BlockStateMeta 9c2c7be8d SPIGOT-7630: Fix crash saving unticked leashed entities 8c1e7c841 PR-1384: Disable certain PlayerProfile tests, if Mojang's services or internet are not available ced93d572 SPIGOT-7626: sendSignChange() has no effect c77362cae SPIGOT-7625: ItemStack with lore cannot be serialized in 1.20.5 ff2004387 SPIGOT-7620: Fix server crash when hoppers transfer items to double chests 8b4abeb03 BUILDTOOLS-676: Downgrade Maven compiler version
2024-04-25 23:21:18 +02:00
@@ -645,7 +645,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
this.setLeftHanded(nbt.getBoolean("LeftHanded"));
if (nbt.contains("DeathLootTable", 8)) {
2024-04-25 01:25:57 +02:00
- this.lootTable = ResourceKey.create(Registries.LOOT_TABLE, new ResourceLocation(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
2024-04-25 19:42:24 +02:00
index fc5913910f5614cd3e10cd9c1aa482a4b70ac260..31b8a8bf78d52b5f11b68e780ec09bf78e7bda84 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
2024-04-25 19:42:24 +02:00
@@ -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 d976a6e3a79a01392a5033b05864d82782a30916..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 {
2024-04-25 01:25:57 +02:00
default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registriesLookup) {
this.clearItemStacks();
if (nbt.contains("LootTable", 8)) {
2024-04-25 01:25:57 +02:00
- this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, new ResourceLocation(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
2024-04-25 01:25:57 +02:00
index f40b2582d9087f9dbb5cab950304698f33fdd879..a99fe191c429bb528209dd0f31b509acf9cccbb5 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
2024-04-25 01:25:57 +02:00
@@ -295,7 +295,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
2024-04-25 01:25:57 +02:00
index f78a9698afc87408fc46de2d3d00c923500885f4..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
2024-04-25 01:25:57 +02:00
@@ -202,7 +202,7 @@ public class BrushableBlockEntity extends BlockEntity {
private boolean tryLoadLootTable(CompoundTag nbt) {
if (nbt.contains("LootTable", 8)) {
2024-04-25 01:25:57 +02:00
- this.lootTable = ResourceKey.create(Registries.LOOT_TABLE, new ResourceLocation(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 {