Mojira Archive
MC-166656

NBT is partially deserialized if it contains an invalid resource location

The bug

If NBT contains an invalid resource location, it will be partially deserialized. This is a confusing behavior because the deserialization result depends on the internal implementation (deserialization order).

How to reproduce

  1. /setblock 0 0 0 minecraft:jigsaw{name: "a", target: "!", pool: "b"}

    An unexpected error occurred trying to execute that command (Non [a-z0-9/._-] character in path of location: minecraft:!)

  2. /data get block 0 0 0 name

    0, 0, 0 has the following block data: "minecraft:a" (changed)

  3. /data get block 0 0 0 target

    0, 0, 0 has the following block data: "minecraft:empty" (unchanged)

  4. /data get block 0 0 0 pool

    0, 0, 0 has the following block data: "minecraft:empty" (unchanged)

Code analysis

The constructor of ResourceLocation throws ResourceLocationException if an invalid location string is passed. Any deserializations that ResourceLocation is instantiated with an arbitrary string can be exited after partially modifying the fields.

// net.minecraft.world.level.block.entity.JigsawBlockEntity

public void load(BlockState state, CompoundTag tag) {
    // ...
    
    name = new ResourceLocation(tag.getString("name"));
    target = new ResourceLocation(tag.getString("target"));
    pool = new ResourceLocation(tag.getString("pool"));

    // ...
}