Update upstream

e2ab12c Change the class source validator to use classloaders for detection. (2039)
This commit is contained in:
NotMyFault 2022-02-28 15:42:03 +01:00
parent 340f8dded3
commit 7db06061f0
No known key found for this signature in database
GPG Key ID: 158F5701A6AAD00C

View File

@ -23,10 +23,10 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.internal.util.LogManagerCompat;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.security.CodeSource;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -45,7 +45,7 @@ public class ClassSourceValidator {
private final Plugin plugin; private final Plugin plugin;
@Nullable @Nullable
private final CodeSource expectedCodeSource; private final ClassLoader expectedClassLoader;
/** /**
* Create a new instance. * Create a new instance.
@ -55,7 +55,7 @@ public class ClassSourceValidator {
public ClassSourceValidator(Plugin plugin) { public ClassSourceValidator(Plugin plugin) {
checkNotNull(plugin, "plugin"); checkNotNull(plugin, "plugin");
this.plugin = plugin; this.plugin = plugin;
this.expectedCodeSource = plugin.getClass().getProtectionDomain().getCodeSource(); this.expectedClassLoader = plugin.getClass().getClassLoader();
} }
/** /**
@ -64,19 +64,29 @@ public class ClassSourceValidator {
* @param classes A list of classes to check * @param classes A list of classes to check
* @return The results * @return The results
*/ */
public Map<Class<?>, CodeSource> findMismatches(List<Class<?>> classes) { public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) {
checkNotNull(classes, "classes"); checkNotNull(classes, "classes");
if (expectedCodeSource == null) { if (expectedClassLoader == null) {
return ImmutableMap.of(); return ImmutableMap.of();
} }
Map<Class<?>, CodeSource> mismatches = new HashMap<>(); Map<Class<?>, Plugin> mismatches = new HashMap<>();
for (Class<?> testClass : classes) { for (Plugin target : Bukkit.getPluginManager().getPlugins()) {
CodeSource testSource = testClass.getProtectionDomain().getCodeSource(); if (target == plugin) {
if (!expectedCodeSource.equals(testSource)) { continue;
mismatches.put(testClass, testSource); }
ClassLoader targetLoader = target.getClass().getClassLoader();
for (Class<?> testClass : classes) {
ClassLoader testSource = null;
try {
testSource = targetLoader.loadClass(testClass.getName()).getClassLoader();
} catch (ClassNotFoundException ignored) {
}
if (testSource != null && testSource != expectedClassLoader) {
mismatches.putIfAbsent(testClass, testSource == targetLoader ? target : null);
}
} }
} }
@ -94,7 +104,7 @@ public class ClassSourceValidator {
if (Boolean.getBoolean("enginehub.disable.class.source.validation")) { if (Boolean.getBoolean("enginehub.disable.class.source.validation")) {
return; return;
} }
Map<Class<?>, CodeSource> mismatches = findMismatches(classes); Map<Class<?>, Plugin> mismatches = findMismatches(classes);
if (mismatches.isEmpty()) { if (mismatches.isEmpty()) {
return; return;
@ -118,9 +128,11 @@ public class ClassSourceValidator {
builder.append("**\n"); builder.append("**\n");
builder.append("** Here are some files that have been overridden:\n"); builder.append("** Here are some files that have been overridden:\n");
builder.append("** \n"); builder.append("** \n");
for (Map.Entry<Class<?>, CodeSource> entry : mismatches.entrySet()) { for (Map.Entry<Class<?>, Plugin> entry : mismatches.entrySet()) {
CodeSource codeSource = entry.getValue(); Plugin badPlugin = entry.getValue();
String url = codeSource != null ? codeSource.getLocation().toExternalForm() : "(unknown)"; String url = badPlugin == null
? "(unknown)"
: badPlugin.getName() + " (" + badPlugin.getClass().getProtectionDomain().getCodeSource().getLocation() + ")";
builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n"); builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n");
} }
builder.append("**\n"); builder.append("**\n");