From f38d64039bffba00cf38e62beddce99292a5dc8b Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Wed, 10 Aug 2016 18:09:45 -0700 Subject: [PATCH] Catch OutOfMemory and StackOverflow errors in Painless since it's safe to do so. --- .../painless/PainlessScriptEngineService.java | 7 ++++--- .../org/elasticsearch/painless/ScriptImpl.java | 5 +++-- .../painless/WhenThingsGoWrongTests.java | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java index 31c4e22dd0c..834593aeb99 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java @@ -127,9 +127,9 @@ public final class PainlessScriptEngineService extends AbstractComponent impleme if (value != null) { compilerSettings.setPicky(Boolean.parseBoolean(value)); } - + value = copy.remove(CompilerSettings.INITIAL_CALL_SITE_DEPTH); - + if (value != null) { compilerSettings.setInitialCallSiteDepth(Integer.parseInt(value)); } @@ -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); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptImpl.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptImpl.java index b303089b339..0d42f8d2336 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptImpl.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptImpl.java @@ -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); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java index b09705803fb..1d60eb9c29a 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java @@ -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);"); + }); + } }