Merge pull request #19936 from jdconrad/errors

Catch OutOfMemory and StackOverflow errors in Painless
This commit is contained in:
Jack Conradson 2016-08-10 18:20:00 -07:00 committed by GitHub
commit a5008bbb78
3 changed files with 23 additions and 5 deletions

View File

@ -162,7 +162,8 @@ public final class PainlessScriptEngineService extends AbstractComponent impleme
return Compiler.compile(loader, scriptName == null ? INLINE_NAME : scriptName, scriptSource, compilerSettings);
}
}, COMPILATION_CONTEXT);
} catch (Exception e) {
// Note that it is safe to catch any of the following errors since Painless is stateless.
} catch (OutOfMemoryError | StackOverflowError | Exception e) {
throw convertToScriptException(scriptName == null ? scriptSource : scriptName, scriptSource, e);
}
}

View File

@ -119,8 +119,9 @@ final class ScriptImpl implements ExecutableScript, LeafSearchScript {
public Object run() {
try {
return executable.execute(variables, scorer, doc, aggregationValue);
} catch (PainlessError | BootstrapMethodError | IllegalAccessError | Exception t) {
throw convertToScriptException(t);
// Note that it is safe to catch any of the following errors since Painless is stateless.
} catch (PainlessError | BootstrapMethodError | OutOfMemoryError | StackOverflowError | Exception e) {
throw convertToScriptException(e);
}
}

View File

@ -19,6 +19,9 @@
package org.elasticsearch.painless;
import org.apache.lucene.util.Constants;
import org.elasticsearch.script.ScriptException;
import java.lang.invoke.WrongMethodTypeException;
import java.util.Arrays;
import java.util.Collections;
@ -218,4 +221,17 @@ public class WhenThingsGoWrongTests extends ScriptTestCase {
exec("BitSet bs = new BitSet(); bs.and(2);");
});
}
public void testOutOfMemoryError() {
assumeTrue("test only happens to work for sure on oracle jre", Constants.JAVA_VENDOR.startsWith("Oracle"));
expectScriptThrows(OutOfMemoryError.class, () -> {
exec("int[] x = new int[Integer.MAX_VALUE - 1];");
});
}
public void testStackOverflowError() {
expectScriptThrows(StackOverflowError.class, () -> {
exec("void recurse(int x, int y) {recurse(x, y)} recurse(1, 2);");
});
}
}