diff options
Diffstat (limited to 'patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch')
-rw-r--r-- | patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch | 276 |
1 files changed, 6 insertions, 270 deletions
diff --git a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch index 348061d5a7..817d23fa98 100644 --- a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch +++ b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch @@ -6,21 +6,13 @@ Subject: [PATCH] Remap reflection calls in plugins using internals Co-authored-by: Jason Penilla <[email protected]> diff --git a/build.gradle.kts b/build.gradle.kts -index c29c309503d5d5defe7991baca34b0d692d57e36..1caa3ef9f0fd71f2bea2e1ea36bb2fa34c6ee689 100644 +index 600b442986fa5ca9dd12f900caa284b854cc30ca..caf738482232039e6e28376daa37b2a3a7465c69 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -32,7 +32,6 @@ dependencies { - implementation("org.ow2.asm:asm-commons:9.7") - implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files - implementation("commons-lang:commons-lang:2.6") -- implementation("net.fabricmc:mapping-io:0.5.0") // Paper - needed to read mappings for stacktrace deobfuscation - runtimeOnly("com.lmax:disruptor:3.4.4") // Paper - - runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6") -@@ -46,6 +45,12 @@ dependencies { +@@ -45,6 +45,12 @@ dependencies { testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest + implementation("net.neoforged:srgutils:1.0.9") // Paper - mappings handling implementation("net.neoforged:AutoRenamingTool:2.0.3") // Paper - remap plugins - implementation("net.neoforged:srgutils:1.0.9") // Paper - remap plugins - bump transitive of ART + // Paper start - Remap reflection + val reflectionRewriterVersion = "0.0.1" + implementation("io.papermc:reflection-rewriter:$reflectionRewriterVersion") @@ -364,165 +356,11 @@ index 8e4229634d41a42b3d93948eebb77def7c0c72b1..38745299ea49f253a410e77557100903 private static final @Nullable String MAPPINGS_HASH = readMappingsHash(); private static final boolean REOBF = checkReobf(); -diff --git a/src/main/java/io/papermc/paper/util/ObfHelper.java b/src/main/java/io/papermc/paper/util/ObfHelper.java -index 3f03d5efcd95e3adb76dc4292b3d2c420fdc58af..9eecb96cb7ec6d6a157ed2c5637e05138c3f55b9 100644 ---- a/src/main/java/io/papermc/paper/util/ObfHelper.java -+++ b/src/main/java/io/papermc/paper/util/ObfHelper.java -@@ -2,19 +2,13 @@ package io.papermc.paper.util; - - import java.io.IOException; - import java.io.InputStream; --import java.io.InputStreamReader; --import java.nio.charset.StandardCharsets; - import java.util.HashMap; - import java.util.HashSet; - import java.util.Map; - import java.util.Objects; - import java.util.Set; --import java.util.function.Function; - import java.util.stream.Collectors; --import net.fabricmc.mappingio.MappingReader; --import net.fabricmc.mappingio.format.MappingFormat; --import net.fabricmc.mappingio.tree.MappingTree; --import net.fabricmc.mappingio.tree.MemoryMappingTree; -+import net.neoforged.srgutils.IMappingFile; - import org.checkerframework.checker.nullness.qual.NonNull; - import org.checkerframework.checker.nullness.qual.Nullable; - import org.checkerframework.framework.qual.DefaultQualifier; -@@ -23,9 +17,6 @@ import org.checkerframework.framework.qual.DefaultQualifier; - public enum ObfHelper { - INSTANCE; - -- public static final String MOJANG_PLUS_YARN_NAMESPACE = "mojang+yarn"; -- public static final String SPIGOT_NAMESPACE = "spigot"; -- - private final @Nullable Map<String, ClassMapping> mappingsByObfName; - private final @Nullable Map<String, ClassMapping> mappingsByMojangName; - -@@ -93,55 +84,73 @@ public enum ObfHelper { - return null; - } - try (final InputStream mappingsInputStream = MappingEnvironment.mappingsStream()) { -- final MemoryMappingTree tree = new MemoryMappingTree(); -- MappingReader.read(new InputStreamReader(mappingsInputStream, StandardCharsets.UTF_8), MappingFormat.TINY_2_FILE, tree); -+ final IMappingFile mappings = IMappingFile.load(mappingsInputStream); // Mappings are mojang->spigot - final Set<ClassMapping> classes = new HashSet<>(); - - final StringPool pool = new StringPool(); -- for (final MappingTree.ClassMapping cls : tree.getClasses()) { -+ for (final IMappingFile.IClass cls : mappings.getClasses()) { - final Map<String, String> methods = new HashMap<>(); -+ final Map<String, String> fields = new HashMap<>(); -+ final Map<String, String> strippedMethods = new HashMap<>(); - -- for (final MappingTree.MethodMapping methodMapping : cls.getMethods()) { -+ for (final IMappingFile.IMethod methodMapping : cls.getMethods()) { - methods.put( - pool.string(methodKey( -- Objects.requireNonNull(methodMapping.getName(SPIGOT_NAMESPACE)), -- Objects.requireNonNull(methodMapping.getDesc(SPIGOT_NAMESPACE)) -+ Objects.requireNonNull(methodMapping.getMapped()), -+ Objects.requireNonNull(methodMapping.getMappedDescriptor()) - )), -- pool.string(Objects.requireNonNull(methodMapping.getName(MOJANG_PLUS_YARN_NAMESPACE))) -+ pool.string(Objects.requireNonNull(methodMapping.getOriginal())) -+ ); -+ -+ strippedMethods.put( -+ pool.string(pool.string(strippedMethodKey( -+ methodMapping.getMapped(), -+ methodMapping.getDescriptor() -+ ))), -+ pool.string(methodMapping.getOriginal()) -+ ); -+ } -+ for (final IMappingFile.IField field : cls.getFields()) { -+ fields.put( -+ pool.string(field.getMapped()), -+ pool.string(field.getOriginal()) - ); - } - - final ClassMapping map = new ClassMapping( -- Objects.requireNonNull(cls.getName(SPIGOT_NAMESPACE)).replace('/', '.'), -- Objects.requireNonNull(cls.getName(MOJANG_PLUS_YARN_NAMESPACE)).replace('/', '.'), -- Map.copyOf(methods) -+ Objects.requireNonNull(cls.getMapped()).replace('/', '.'), -+ Objects.requireNonNull(cls.getOriginal()).replace('/', '.'), -+ Map.copyOf(methods), -+ Map.copyOf(fields), -+ Map.copyOf(strippedMethods) - ); - classes.add(map); - } - - return Set.copyOf(classes); - } catch (final IOException ex) { -- System.err.println("Failed to load mappings for stacktrace deobfuscation."); -+ System.err.println("Failed to load mappings."); - ex.printStackTrace(); - return null; - } - } - -- public static String methodKey(final String obfName, final String obfDescriptor) { -- return obfName + obfDescriptor; -+ public static String strippedMethodKey(final String methodName, final String methodDescriptor) { -+ final String methodKey = methodKey(methodName, methodDescriptor); -+ final int returnDescriptorEnd = methodKey.indexOf(')'); -+ return methodKey.substring(0, returnDescriptorEnd + 1); - } - -- private static final class StringPool { -- private final Map<String, String> pool = new HashMap<>(); -- -- public String string(final String string) { -- return this.pool.computeIfAbsent(string, Function.identity()); -- } -+ public static String methodKey(final String methodName, final String methodDescriptor) { -+ return methodName + methodDescriptor; - } - - public record ClassMapping( - String obfName, - String mojangName, -- Map<String, String> methodsByObf -+ Map<String, String> methodsByObf, -+ Map<String, String> fieldsByObf, -+ // obf name with mapped desc to mapped name. return value is excluded from desc as reflection doesn't use it -+ Map<String, String> strippedMethods - ) {} - } diff --git a/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java b/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java -index eb910d4abf91488fa7cf1f5d47e0ee916c47f512..0b65fdf53124f3dd042b2363b1b8df8e1ca7de00 100644 +index 242811578a786e3807a1a7019d472d5a68f87116..0b65fdf53124f3dd042b2363b1b8df8e1ca7de00 100644 --- a/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java +++ b/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java -@@ -1,12 +1,11 @@ - package io.papermc.paper.util; - - import io.papermc.paper.configuration.GlobalConfiguration; --import it.unimi.dsi.fastutil.ints.IntArrayList; --import it.unimi.dsi.fastutil.ints.IntList; -+import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; - import java.io.IOException; - import java.io.InputStream; - import java.util.Collections; --import java.util.HashMap; - import java.util.LinkedHashMap; - import java.util.Map; - import org.checkerframework.checker.nullness.qual.NonNull; -@@ -22,14 +21,17 @@ import org.objectweb.asm.Opcodes; - public enum StacktraceDeobfuscator { - INSTANCE; - -- private final Map<Class<?>, Map<String, IntList>> lineMapCache = Collections.synchronizedMap(new LinkedHashMap<>(128, 0.75f, true) { -+ private final Map<Class<?>, Int2ObjectMap<String>> lineMapCache = Collections.synchronizedMap(new LinkedHashMap<>(128, 0.75f, true) { - @Override -- protected boolean removeEldestEntry(final Map.Entry<Class<?>, Map<String, IntList>> eldest) { -+ protected boolean removeEldestEntry(final Map.Entry<Class<?>, Int2ObjectMap<String>> eldest) { - return this.size() > 127; - } +@@ -29,6 +29,9 @@ public enum StacktraceDeobfuscator { }); public void deobfuscateThrowable(final Throwable throwable) { @@ -532,7 +370,7 @@ index eb910d4abf91488fa7cf1f5d47e0ee916c47f512..0b65fdf53124f3dd042b2363b1b8df8e if (GlobalConfiguration.get() != null && !GlobalConfiguration.get().logging.deobfuscateStacktraces) { // handle null as true return; } -@@ -45,6 +47,9 @@ public enum StacktraceDeobfuscator { +@@ -44,6 +47,9 @@ public enum StacktraceDeobfuscator { } public StackTraceElement[] deobfuscateStacktrace(final StackTraceElement[] traceElements) { @@ -542,108 +380,6 @@ index eb910d4abf91488fa7cf1f5d47e0ee916c47f512..0b65fdf53124f3dd042b2363b1b8df8e if (GlobalConfiguration.get() != null && !GlobalConfiguration.get().logging.deobfuscateStacktraces) { // handle null as true return traceElements; } -@@ -89,18 +94,7 @@ public enum StacktraceDeobfuscator { - } - - private @Nullable String determineMethodForLine(final Class<?> clazz, final int lineNumber) { -- final Map<String, IntList> lineMap = this.lineMapCache.computeIfAbsent(clazz, StacktraceDeobfuscator::buildLineMap); -- for (final var entry : lineMap.entrySet()) { -- final String methodKey = entry.getKey(); -- final IntList lines = entry.getValue(); -- for (int i = 0, linesSize = lines.size(); i < linesSize; i++) { -- final int num = lines.getInt(i); -- if (num == lineNumber) { -- return methodKey; -- } -- } -- } -- return null; -+ return this.lineMapCache.computeIfAbsent(clazz, StacktraceDeobfuscator::buildLineMap).get(lineNumber); - } - - private static String sourceFileName(final String fullClassName) { -@@ -112,34 +106,27 @@ public enum StacktraceDeobfuscator { - return rootClassName + ".java"; - } - -- private static Map<String, IntList> buildLineMap(final Class<?> key) { -- final Map<String, IntList> lineMap = new HashMap<>(); -+ private static Int2ObjectMap<String> buildLineMap(final Class<?> key) { -+ final StringPool pool = new StringPool(); -+ final Int2ObjectMap<String> lineMap = new Int2ObjectOpenHashMap<>(); - final class LineCollectingMethodVisitor extends MethodVisitor { -- private final IntList lines = new IntArrayList(); - private final String name; - private final String descriptor; - -- LineCollectingMethodVisitor(String name, String descriptor) { -+ LineCollectingMethodVisitor(final String name, final String descriptor) { - super(Opcodes.ASM9); - this.name = name; - this.descriptor = descriptor; - } - - @Override -- public void visitLineNumber(int line, Label start) { -- super.visitLineNumber(line, start); -- this.lines.add(line); -- } -- -- @Override -- public void visitEnd() { -- super.visitEnd(); -- lineMap.put(ObfHelper.methodKey(this.name, this.descriptor), this.lines); -+ public void visitLineNumber(final int line, final Label start) { -+ lineMap.put(line, pool.string(ObfHelper.methodKey(this.name, this.descriptor))); - } - } - final ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM9) { - @Override -- public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { -+ public MethodVisitor visitMethod(final int access, final String name, final String descriptor, final String signature, final String[] exceptions) { - return new LineCollectingMethodVisitor(name, descriptor); - } - }; -diff --git a/src/main/java/io/papermc/paper/util/StringPool.java b/src/main/java/io/papermc/paper/util/StringPool.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c0a486cb46ff30353c3ff09567891cd36238eeb4 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/StringPool.java -@@ -0,0 +1,34 @@ -+package io.papermc.paper.util; -+ -+import java.util.HashMap; -+import java.util.Map; -+import java.util.function.Function; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+/** -+ * De-duplicates {@link String} instances without using {@link String#intern()}. -+ * -+ * <p>Interning may not be desired as we may want to use the heap for our pool, -+ * so it can be garbage collected as normal, etc.</p> -+ * -+ * <p>Additionally, interning can be slow due to the potentially large size of the -+ * pool (as it is shared for the entire JVM), and because most JVMs implement -+ * it using JNI.</p> -+ */ -+@DefaultQualifier(NonNull.class) -+public final class StringPool { -+ private final Map<String, String> pool; -+ -+ public StringPool() { -+ this(new HashMap<>()); -+ } -+ -+ public StringPool(final Map<String, String> map) { -+ this.pool = map; -+ } -+ -+ public String string(final String string) { -+ return this.pool.computeIfAbsent(string, Function.identity()); -+ } -+} diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java index 457a963ee6ebd3cf5c3831f6660e3850335af49f..61744d8fde3ba98585cf261fc09f0acc042b67b8 100644 --- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java |