aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0978-Validate-ResourceLocation-in-NBT-reading.patch
blob: 2f94b7ad0323062f0e755b4c8bc310479c4ad64a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
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 4591011a142f33f0c0ff84a2765cededde0e0c57..c0bfce7266bbdfe0c5a753367032eb333f56c182 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -871,12 +871,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 9ecabac9e95bb0b550260770fcc713ad82070d0b..fd093e5bc79a44e02f57bacd8273dc87342f5709 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -607,7 +607,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 618de60680de015bc68bf95a68eda98db7bab3c5..d14eab0d83d629a4522bf3f7d789d2853eb84f06 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -560,7 +560,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"));
         }