aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0994-Validate-ResourceLocation-in-NBT-reading.patch
blob: 12f95acee8308d536a3e59bd91ca6dea46d283ea (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
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 9da8d56ff3768fb37d1ab89300da4eca19e6218d..edc723ea5ca3a325106e7af38c60dbf9f0f5fb77 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -618,7 +618,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/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 6d21d478a32ef8aff3961cba7441a0be384663b0..2c4916982add2e8d1fbafd13efc82c6be30e9b70 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"));
         }