From d267f74a0b587aec8784677d0734df1a8e396546 Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Mon, 3 Jun 2024 07:18:17 +1000 Subject: [PATCH] SPIGOT-7676: Enforce locale parameter in toLowerCase and toUpperCase method calls and always use root locale By: DerFrZocker --- paper-server/checkstyle.xml | 10 ++++++++++ .../net/minecraft/server/MinecraftServer.patch | 2 +- .../java/org/bukkit/craftbukkit/CraftServer.java | 16 ++++++++-------- .../craftbukkit/util/CraftChatMessage.java | 3 ++- .../src/test/java/org/bukkit/SoundTest.java | 3 ++- .../DeprecatedItemMetaCustomValueTest.java | 3 ++- .../inventory/PersistentDataContainerTest.java | 3 ++- .../generator/structure/StructureTest.java | 5 +++-- .../generator/structure/StructureTypeTest.java | 5 +++-- .../bukkit/registry/RegistryConstantsTest.java | 5 +++-- 10 files changed, 36 insertions(+), 19 deletions(-) diff --git a/paper-server/checkstyle.xml b/paper-server/checkstyle.xml index ec61ec7570..5c7f6a5d51 100644 --- a/paper-server/checkstyle.xml +++ b/paper-server/checkstyle.xml @@ -26,6 +26,16 @@ + + + + + + + + + + diff --git a/paper-server/nms-patches/net/minecraft/server/MinecraftServer.patch b/paper-server/nms-patches/net/minecraft/server/MinecraftServer.patch index 77acf286fc..7d289eb047 100644 --- a/paper-server/nms-patches/net/minecraft/server/MinecraftServer.patch +++ b/paper-server/nms-patches/net/minecraft/server/MinecraftServer.patch @@ -188,7 +188,7 @@ + dimension = -999; + } + -+ String worldType = (dimension == -999) ? dimensionKey.location().getNamespace() + "_" + dimensionKey.location().getPath() : org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(); ++ String worldType = (dimension == -999) ? dimensionKey.location().getNamespace() + "_" + dimensionKey.location().getPath() : org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(Locale.ROOT); + String name = (dimensionKey == WorldDimension.OVERWORLD) ? s : s + "_" + worldType; + if (dimension != 0) { + File newWorld = Convertable.getStorageFolder(new File(name).toPath(), dimensionKey).toFile(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 6b341eece4..18e347dd5e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -584,10 +584,10 @@ public final class CraftServer implements Server { return found; } - String lowerName = name.toLowerCase(java.util.Locale.ENGLISH); + String lowerName = name.toLowerCase(Locale.ROOT); int delta = Integer.MAX_VALUE; for (Player player : getOnlinePlayers()) { - if (player.getName().toLowerCase(java.util.Locale.ENGLISH).startsWith(lowerName)) { + if (player.getName().toLowerCase(Locale.ROOT).startsWith(lowerName)) { int curDelta = Math.abs(player.getName().length() - lowerName.length()); if (curDelta < delta) { found = player; @@ -641,7 +641,7 @@ public final class CraftServer implements Server { matchedPlayers.add(iterPlayer); break; } - if (iterPlayerName.toLowerCase(java.util.Locale.ENGLISH).contains(partialName.toLowerCase(java.util.Locale.ENGLISH))) { + if (iterPlayerName.toLowerCase(Locale.ROOT).contains(partialName.toLowerCase(Locale.ROOT))) { // Partial match matchedPlayers.add(iterPlayer); } @@ -1203,7 +1203,7 @@ public final class CraftServer implements Server { } else if (name.equals(levelName + "_the_end")) { worldKey = net.minecraft.world.level.World.END; } else { - worldKey = ResourceKey.create(Registries.DIMENSION, new MinecraftKey(name.toLowerCase(java.util.Locale.ENGLISH))); + worldKey = ResourceKey.create(Registries.DIMENSION, new MinecraftKey(name.toLowerCase(Locale.ROOT))); } // If set to not keep spawn in memory (changed from default) then adjust rule accordingly @@ -1213,7 +1213,7 @@ public final class CraftServer implements Server { WorldServer internal = (WorldServer) new WorldServer(console, console.executor, worldSession, worlddata, worldKey, worlddimension, getServer().progressListenerFactory.create(worlddata.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)), worlddata.isDebugWorld(), j, creator.environment() == Environment.NORMAL ? list : ImmutableList.of(), true, console.overworld().getRandomSequences(), creator.environment(), generator, biomeProvider); - if (!(worlds.containsKey(name.toLowerCase(java.util.Locale.ENGLISH)))) { + if (!(worlds.containsKey(name.toLowerCase(Locale.ROOT)))) { return null; } @@ -1273,7 +1273,7 @@ public final class CraftServer implements Server { getLogger().log(Level.SEVERE, null, ex); } - worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH)); + worlds.remove(world.getName().toLowerCase(Locale.ROOT)); console.removeLevel(handle); return true; } @@ -1286,7 +1286,7 @@ public final class CraftServer implements Server { public World getWorld(String name) { Preconditions.checkArgument(name != null, "name cannot be null"); - return worlds.get(name.toLowerCase(java.util.Locale.ENGLISH)); + return worlds.get(name.toLowerCase(Locale.ROOT)); } @Override @@ -1305,7 +1305,7 @@ public final class CraftServer implements Server { System.out.println("World " + world.getName() + " is a duplicate of another world and has been prevented from loading. Please delete the uid.dat file from " + world.getName() + "'s world directory if you want to be able to load the duplicate world."); return; } - worlds.put(world.getName().toLowerCase(java.util.Locale.ENGLISH), world); + worlds.put(world.getName().toLowerCase(Locale.ROOT), world); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index 169e383086..fff6875dcf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableMap.Builder; import com.google.gson.JsonParseException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; @@ -80,7 +81,7 @@ public final class CraftChatMessage { } switch (groupId) { case 1: - char c = match.toLowerCase(java.util.Locale.ENGLISH).charAt(1); + char c = match.toLowerCase(Locale.ROOT).charAt(1); EnumChatFormat format = formatMap.get(c); if (c == 'x') { diff --git a/paper-server/src/test/java/org/bukkit/SoundTest.java b/paper-server/src/test/java/org/bukkit/SoundTest.java index ff62148d66..5137b2213a 100644 --- a/paper-server/src/test/java/org/bukkit/SoundTest.java +++ b/paper-server/src/test/java/org/bukkit/SoundTest.java @@ -3,6 +3,7 @@ package org.bukkit; import static org.bukkit.support.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; +import java.util.Locale; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.MinecraftKey; import org.bukkit.craftbukkit.CraftSound; @@ -21,7 +22,7 @@ public class SoundTest extends AbstractTestingBase { @Test public void testReverse() { for (MinecraftKey effect : BuiltInRegistries.SOUND_EVENT.keySet()) { - assertNotNull(Sound.valueOf(effect.getPath().replace('.', '_').toUpperCase(java.util.Locale.ENGLISH)), effect + ""); + assertNotNull(Sound.valueOf(effect.getPath().replace('.', '_').toUpperCase(Locale.ROOT)), effect + ""); } } diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java index d4ffcee4a6..89403f0401 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.*; import java.io.StringReader; import java.lang.reflect.Array; import java.nio.ByteBuffer; +import java.util.Locale; import java.util.Map; import java.util.UUID; import org.bukkit.Bukkit; @@ -82,7 +83,7 @@ public class DeprecatedItemMetaCustomValueTest extends AbstractTestingBase { } private NamespacedKey requestKey(String keyName) { - return new NamespacedKey("test-plugin", keyName.toLowerCase()); + return new NamespacedKey("test-plugin", keyName.toLowerCase(Locale.ROOT)); } /* diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java index ac78dc6315..bb8e1e7e82 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java @@ -7,6 +7,7 @@ import java.lang.reflect.Array; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.function.BiConsumer; @@ -96,7 +97,7 @@ public class PersistentDataContainerTest extends AbstractTestingBase { } private static NamespacedKey requestKey(String keyName) { - return new NamespacedKey("test-plugin", keyName.toLowerCase()); + return new NamespacedKey("test-plugin", keyName.toLowerCase(Locale.ROOT)); } @Test diff --git a/paper-server/src/test/java/org/bukkit/generator/structure/StructureTest.java b/paper-server/src/test/java/org/bukkit/generator/structure/StructureTest.java index 8c0669cf93..2c7e2236aa 100644 --- a/paper-server/src/test/java/org/bukkit/generator/structure/StructureTest.java +++ b/paper-server/src/test/java/org/bukkit/generator/structure/StructureTest.java @@ -3,6 +3,7 @@ package org.bukkit.generator.structure; import static org.junit.jupiter.api.Assertions.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Locale; import net.minecraft.core.IRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.MinecraftKey; @@ -25,7 +26,7 @@ public class StructureTest extends AbstractTestingBase { } String name = field.getName(); - assertNotNull(Registry.STRUCTURE.get(NamespacedKey.fromString(name.toLowerCase())), "No structure for field name " + name); + assertNotNull(Registry.STRUCTURE.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))), "No structure for field name " + name); } } @@ -36,7 +37,7 @@ public class StructureTest extends AbstractTestingBase { MinecraftKey minecraftKey = structureBuiltInRegistries.getKey(structure); try { - Structure bukkit = (Structure) Structure.class.getField(minecraftKey.getPath().toUpperCase()).get(null); + Structure bukkit = (Structure) Structure.class.getField(minecraftKey.getPath().toUpperCase(Locale.ROOT)).get(null); assertEquals(minecraftKey, CraftNamespacedKey.toMinecraft(bukkit.getKey()), "Keys are not the same for " + minecraftKey); } catch (NoSuchFieldException e) { diff --git a/paper-server/src/test/java/org/bukkit/generator/structure/StructureTypeTest.java b/paper-server/src/test/java/org/bukkit/generator/structure/StructureTypeTest.java index 69bccab363..942ff7cd34 100644 --- a/paper-server/src/test/java/org/bukkit/generator/structure/StructureTypeTest.java +++ b/paper-server/src/test/java/org/bukkit/generator/structure/StructureTypeTest.java @@ -3,6 +3,7 @@ package org.bukkit.generator.structure; import static org.junit.jupiter.api.Assertions.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Locale; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.MinecraftKey; import org.bukkit.NamespacedKey; @@ -24,7 +25,7 @@ public class StructureTypeTest extends AbstractTestingBase { } String name = field.getName(); - assertNotNull(Registry.STRUCTURE_TYPE.get(NamespacedKey.fromString(name.toLowerCase())), "No enchantment for field name " + name); + assertNotNull(Registry.STRUCTURE_TYPE.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))), "No enchantment for field name " + name); } } @@ -34,7 +35,7 @@ public class StructureTypeTest extends AbstractTestingBase { MinecraftKey minecraftKey = BuiltInRegistries.STRUCTURE_TYPE.getKey(structureType); try { - StructureType bukkit = (StructureType) StructureType.class.getField(minecraftKey.getPath().toUpperCase()).get(null); + StructureType bukkit = (StructureType) StructureType.class.getField(minecraftKey.getPath().toUpperCase(Locale.ROOT)).get(null); assertEquals(minecraftKey, CraftNamespacedKey.toMinecraft(bukkit.getKey()), "Keys are not the same for " + minecraftKey); } catch (NoSuchFieldException e) { diff --git a/paper-server/src/test/java/org/bukkit/registry/RegistryConstantsTest.java b/paper-server/src/test/java/org/bukkit/registry/RegistryConstantsTest.java index 38b73d90fe..f50c944d48 100644 --- a/paper-server/src/test/java/org/bukkit/registry/RegistryConstantsTest.java +++ b/paper-server/src/test/java/org/bukkit/registry/RegistryConstantsTest.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import net.minecraft.core.IRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.MinecraftKey; @@ -48,7 +49,7 @@ public class RegistryConstantsTest extends AbstractTestingBase { } String name = field.getName(); - NamespacedKey key = NamespacedKey.fromString(name.toLowerCase()); + NamespacedKey key = NamespacedKey.fromString(name.toLowerCase(Locale.ROOT)); if (registry.get(key) == null) { excessKeys.add(key); } @@ -67,7 +68,7 @@ public class RegistryConstantsTest extends AbstractTestingBase { try { @SuppressWarnings("unchecked") - T bukkitObject = (T) clazz.getField(minecraftKey.getPath().toUpperCase()).get(null); + T bukkitObject = (T) clazz.getField(minecraftKey.getPath().toUpperCase(Locale.ROOT)).get(null); assertEquals(minecraftKey, CraftNamespacedKey.toMinecraft(bukkitObject.getKey()), "Keys are not the same for " + minecraftKey); } catch (NoSuchFieldException e) {