Merge pull request #755 from OneShotMC/master

fix //calc still being able to crash servers
This commit is contained in:
Jesse Boyd 2017-10-01 17:32:23 +11:00 committed by GitHub
commit 3babe53f91
3 changed files with 99 additions and 15 deletions

View File

@ -116,6 +116,7 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter;
import com.sk89q.worldedit.internal.command.WorldEditBinding;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment;
import com.sk89q.worldedit.internal.expression.runtime.For;
import com.sk89q.worldedit.internal.expression.runtime.Functions;
import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
@ -645,6 +646,7 @@ public class Fawe {
WorldEditExpressionEnvironment.inject(); // Optimizations + features
Expression.inject(); // Optimizations
Functions.inject(); // Optimizations
For.inject(); // Fixes
// BlockData
BlockData.inject(); // Temporary fix for 1.9.4
BundledBlockData.inject(); // Add custom rotation

View File

@ -87,10 +87,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@ -552,21 +549,30 @@ public class UtilityCommands extends MethodCommands {
try {
FaweLimit limit = FawePlayer.wrap(actor).getLimit();
final Expression expression = Expression.compile(input);
double[] result = new double[] { Double.NaN };
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Double> futureResult = executor.submit(new Callable<Double>() {
@Override
public Double call() throws Exception {
return expression.evaluate();
}
});
Double result = Double.NaN;
try {
executor.invokeAll(Arrays.asList(new Callable<Object>() {
@Override
public Object call() throws Exception {
result[0] = expression.evaluate();
return null;
}
}), limit.MAX_EXPRESSION_MS, TimeUnit.MILLISECONDS); // Default timeout of 50 milliseconds to prevent abuse.
result = futureResult.get(limit.MAX_EXPRESSION_MS, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
futureResult.cancel(true);
e.printStackTrace();
}
executor.shutdown();
actor.print(BBC.getPrefix() + "= " + result[0]);
executor.shutdownNow();
actor.print(BBC.getPrefix() + "= " + result);
} catch (EvaluationException e) {
actor.printError(String.format(
"'%s' could not be parsed as a valid expression", input));

View File

@ -0,0 +1,76 @@
package com.sk89q.worldedit.internal.expression.runtime;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.parser.ParserException;
public class For extends Node {
RValue init;
RValue condition;
RValue increment;
RValue body;
public For(int position, RValue init, RValue condition, RValue increment, RValue body) {
super(position);
this.init = init;
this.condition = condition;
this.increment = increment;
this.body = body;
}
public double getValue() throws EvaluationException {
int iterations = 0;
double ret = 0.0D;
this.init.getValue();
for(; this.condition.getValue() > 0.0D; this.increment.getValue()) {
if(iterations > 256) {
throw new EvaluationException(this.getPosition(), "Loop exceeded 256 iterations.");
}
if(Thread.currentThread().isInterrupted()){
throw new EvaluationException(this.getPosition(), "Thread has been interuppted.");
}
++iterations;
try {
ret = this.body.getValue();
} catch (BreakException var5) {
if(!var5.doContinue) {
return ret;
}
}
}
return ret;
}
public char id() {
return 'F';
}
public String toString() {
return "for (" + this.init + "; " + this.condition + "; " + this.increment + ") { " + this.body + " }";
}
public RValue optimize() throws EvaluationException {
RValue newCondition = this.condition.optimize();
return (RValue)(newCondition instanceof Constant && newCondition.getValue() <= 0.0D?(new Sequence(this.getPosition(), new RValue[]{this.init, new Constant(this.getPosition(), 0.0D)})).optimize():new For(this.getPosition(), this.init.optimize(), newCondition, this.increment.optimize(), this.body.optimize()));
}
public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException {
this.init = this.init.bindVariables(expression, false);
this.condition = this.condition.bindVariables(expression, false);
this.increment = this.increment.bindVariables(expression, false);
this.body = this.body.bindVariables(expression, false);
return this;
}
public static Class<For> inject() {
return For.class;
}
}