mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
7d18cb068e
This prevent the creaking from being pushed with knockback enchant when it can't move
173 lines
12 KiB
Diff
173 lines
12 KiB
Diff
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/nbt/NbtUtils.java
|
|
+++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/resources/ResourceLocation.java
|
|
+++ b/src/main/java/net/minecraft/resources/ResourceLocation.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/RandomizableContainer.java
|
|
+++ b/src/main/java/net/minecraft/world/RandomizableContainer.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
@@ -0,0 +0,0 @@ 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/Leashable.java b/src/main/java/net/minecraft/world/entity/Leashable.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Leashable.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Leashable.java
|
|
@@ -0,0 +0,0 @@ public interface Leashable {
|
|
@Nullable
|
|
private static Leashable.LeashData readLeashDataInternal(CompoundTag nbt) {
|
|
if (nbt.contains("leash", 10)) {
|
|
- return new Leashable.LeashData(Either.left(nbt.getCompound("leash").getUUID("UUID")));
|
|
+ // Paper start
|
|
+ final CompoundTag leashTag = nbt.getCompound("leash");
|
|
+ if (!leashTag.hasUUID("UUID")) {
|
|
+ return null;
|
|
+ }
|
|
+ return new Leashable.LeashData(Either.left(leashTag.getUUID("UUID")));
|
|
+ // Paper end
|
|
} else {
|
|
if (nbt.contains("leash", 11)) {
|
|
Either<UUID, BlockPos> either = (Either) NbtUtils.readBlockPos(nbt, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error
|
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
|
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
|
this.readLeashData(nbt);
|
|
this.setLeftHanded(nbt.getBoolean("LeftHanded"));
|
|
if (nbt.contains("DeathLootTable", 8)) {
|
|
- this.lootTable = Optional.of(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("DeathLootTable"))));
|
|
+ this.lootTable = Optional.ofNullable(ResourceLocation.tryParse(nbt.getString("DeathLootTable"))).map((rs) -> ResourceKey.create(Registries.LOOT_TABLE, rs)); // Paper - Validate ResourceLocation
|
|
} else {
|
|
this.lootTable = Optional.empty();
|
|
}
|
|
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
|
@@ -0,0 +0,0 @@ public interface ContainerEntity extends Container, MenuProvider {
|
|
default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registries) {
|
|
this.clearItemStacks();
|
|
if (nbt.contains("LootTable", 8)) {
|
|
- this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable"))));
|
|
+ this.setContainerLootTable(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.getContainerLootTable() != 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
|
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
|
while (iterator.hasNext()) {
|
|
String s = (String) iterator.next();
|
|
|
|
- this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(s)), nbttagcompound1.getInt(s));
|
|
+ // Paper start - Validate ResourceLocation
|
|
+ final ResourceLocation resourceLocation = ResourceLocation.tryParse(s);
|
|
+ if (resourceLocation != null) {
|
|
+ this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, resourceLocation), nbttagcompound1.getInt(s));
|
|
+ }
|
|
}
|
|
|
|
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
|
@@ -0,0 +0,0 @@ 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 {
|