Skript 2.8+ unsafe Fix #29

Open
rigbot2 wants to merge 1 commits from rigbot2/skript-db:master into master
Showing only changes of commit 1dc6410667 - Show all commits

View File

@ -1,94 +1,85 @@
package com.btk5h.skriptdb; package com.btk5h.skriptdb;
import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.VariableString;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import org.bukkit.event.Event;
import ch.njol.skript.ScriptLoader;
import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.VariableString;
import ch.njol.skript.lang.parser.ParserInstance;
public class SkriptUtil { public class SkriptUtil {
private static final Field STRING;
private static final Field EXPR;
private static final Field STRING; static {
private static final Field EXPR; Field stringField = null;
Field exprField = null;
static { String[] possibleStringFields = {"string", "stringValue", "rawString"};
STRING = tryGetOldStringField() for (String fieldName : possibleStringFields) {
.or(() -> tryGetNewStringField()) try {
.orElseGet(() -> { stringField = VariableString.class.getDeclaredField(fieldName);
Skript.error("Skript's 'string' field could not be resolved."); stringField.setAccessible(true);
return null; break;
}); } catch (NoSuchFieldException ignored) {}
}
Field f = null; if (stringField == null) {
try { for (Field field : VariableString.class.getDeclaredFields()) {
Optional<Class<?>> expressionInfo = Arrays.stream(VariableString.class.getDeclaredClasses()) if (field.getType().isArray() && field.getType().getComponentType() == Object.class) {
.filter(cls -> cls.getSimpleName().equals("ExpressionInfo")) try {
.findFirst(); field.setAccessible(true);
if (expressionInfo.isPresent()) { stringField = field;
Class<?> expressionInfoClass = expressionInfo.get(); break;
f = expressionInfoClass.getDeclaredField("expr"); } catch (SecurityException ignored) {}
f.setAccessible(true); }
} else { }
Skript.error("Skript's 'ExpressionInfo' class could not be resolved."); }
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
Skript.error("Skript's 'expr' field could not be resolved.");
}
EXPR = f;
}
public static Object[] getTemplateString(VariableString vs) { try {
try { Optional<Class<?>> expressionInfo = Arrays.stream(VariableString.class.getDeclaredClasses())
return (Object[]) STRING.get(vs); .filter(cls -> cls.getSimpleName().equals("ExpressionInfo"))
} catch (IllegalAccessException e) { .findFirst();
throw new RuntimeException(e);
}
}
public static Expression<?> getExpressionFromInfo(Object o) { if (expressionInfo.isPresent()) {
try { Class<?> expressionInfoClass = expressionInfo.get();
return (Expression<?>) EXPR.get(o); try {
} catch (IllegalAccessException e) { exprField = expressionInfoClass.getDeclaredField("expr");
throw new RuntimeException(e); exprField.setAccessible(true);
} } catch (NoSuchFieldException e) {
} for (Field field : expressionInfoClass.getDeclaredFields()) {
if (Expression.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
exprField = field;
break;
}
}
}
}
} catch (Exception ignored) {}
@SuppressWarnings("deprecation") STRING = stringField;
public static boolean isCurrentEvent(Class<? extends Event> event) { EXPR = exprField;
try {
Class.forName("ch.njol.skript.lang.parser.ParserInstance");
return ParserInstance.get().isCurrentEvent(event);
} catch (ClassNotFoundException e) {
return ScriptLoader.isCurrentEvent(event);
}
}
if (STRING == null && EXPR == null) {
Skript.error("Failed to initialize SkriptUtil: Could not find required fields");
}
}
private static Optional<Field> tryGetOldStringField() { public static Object[] getTemplateString(VariableString vs) {
try { try {
Field f = VariableString.class.getDeclaredField("string"); return STRING != null ? (Object[]) STRING.get(vs) : new Object[]{vs.toString()};
f.setAccessible(true); } catch (IllegalAccessException e) {
return Optional.of(f); return new Object[]{vs.toString()};
} catch (NoSuchFieldException e) { }
return Optional.empty(); }
}
}
private static Optional<Field> tryGetNewStringField() {
try {
Field f = VariableString.class.getDeclaredField("strings");
f.setAccessible(true);
return Optional.of(f);
} catch (NoSuchFieldException e) {
return Optional.empty();
}
}
public static Expression<?> getExpressionFromInfo(Object o) {
try {
return EXPR != null ? (Expression<?>) EXPR.get(o) : null;
} catch (IllegalAccessException e) {
return null;
}
}
} }