Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop runtime script from emitting too many values #61938

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public abstract class AbstractLongScriptFieldScript extends AbstractScriptFieldS
private long[] values = new long[1];
private int count;

public AbstractLongScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public AbstractLongScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(fieldName, params, searchLookup, ctx);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.elasticsearch.search.lookup.SourceLookup;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;

Expand All @@ -27,6 +28,11 @@
* {@link AggregationScript} but hopefully with less historical baggage.
*/
public abstract class AbstractScriptFieldScript {
/**
* The maximum number of values a script should be allowed to emit.
*/
static final int MAX_VALUES = 100;

public static <F> ScriptContext<F> newContext(String name, Class<F> factoryClass) {
return new ScriptContext<F>(
name + "_script_field",
Expand Down Expand Up @@ -54,10 +60,12 @@ public static <F> ScriptContext<F> newContext(String name, Class<F> factoryClass
value -> ((SourceLookup) value).loadSourceIfNeeded()
);

protected final String fieldName;
private final Map<String, Object> params;
private final LeafSearchLookup leafSearchLookup;

public AbstractScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
public AbstractScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
this.fieldName = fieldName;
this.leafSearchLookup = searchLookup.getLeafSearchLookup(ctx);
params = new HashMap<>(params);
params.put("_source", leafSearchLookup.source());
Expand Down Expand Up @@ -93,5 +101,19 @@ public final Map<String, ScriptDocValues<?>> getDoc() {
return leafSearchLookup.doc();
}

protected final void checkMaxSize(int currentSize) {
javanna marked this conversation as resolved.
Show resolved Hide resolved
if (currentSize >= MAX_VALUES) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"Runtime field [%s] is emitting [%s] values while the maximum number of values allowed is [%s]",
fieldName,
currentSize + 1,
MAX_VALUES
)
);
}
}

public abstract void execute();
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static List<Whitelist> whitelist() {
public static final String[] PARAMETERS = {};

public interface Factory extends ScriptFactory {
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup);
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
}

public interface LeafFactory {
Expand All @@ -38,8 +38,8 @@ public interface LeafFactory {
private int trues;
private int falses;

public BooleanScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public BooleanScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(fieldName, params, searchLookup, ctx);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static List<Whitelist> whitelist() {
public static final String[] PARAMETERS = {};

public interface Factory extends ScriptFactory {
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup, DateFormatter formatter);
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup, DateFormatter formatter);
}

public interface LeafFactory {
Expand All @@ -39,8 +39,14 @@ public interface LeafFactory {

private final DateFormatter formatter;

public DateScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, DateFormatter formatter, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public DateScriptFieldScript(
String fieldName,
Map<String, Object> params,
SearchLookup searchLookup,
DateFormatter formatter,
LeafReaderContext ctx
) {
super(fieldName, params, searchLookup, ctx);
this.formatter = formatter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static List<Whitelist> whitelist() {
public static final String[] PARAMETERS = {};

public interface Factory extends ScriptFactory {
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup);
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
}

public interface LeafFactory {
Expand All @@ -38,8 +38,8 @@ public interface LeafFactory {
private double[] values = new double[1];
private int count;

public DoubleScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public DoubleScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(fieldName, params, searchLookup, ctx);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static List<Whitelist> whitelist() {
public static final String[] PARAMETERS = {};

public interface Factory extends ScriptFactory {
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup);
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
}

public interface LeafFactory {
Expand All @@ -59,8 +59,8 @@ public interface LeafFactory {
private BytesRef[] values = new BytesRef[1];
private int count;

public IpScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public IpScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(fieldName, params, searchLookup, ctx);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ static List<Whitelist> whitelist() {
public static final String[] PARAMETERS = {};

public interface Factory extends ScriptFactory {
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup);
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
}

public interface LeafFactory {
LongScriptFieldScript newInstance(LeafReaderContext ctx) throws IOException;
}

public LongScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public LongScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(fieldName, params, searchLookup, ctx);
}

public static class EmitValue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public abstract class StringScriptFieldScript extends AbstractScriptFieldScript {
/**
* The maximum number of chars a script should be allowed to emit.
*/
public static final long MAX_CHARS = 1024 * 1024;

public static final ScriptContext<Factory> CONTEXT = newContext("string_script_field", Factory.class);

static List<Whitelist> whitelist() {
Expand All @@ -28,17 +34,18 @@ static List<Whitelist> whitelist() {
public static final String[] PARAMETERS = {};

public interface Factory extends ScriptFactory {
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup);
LeafFactory newFactory(String fieldName, Map<String, Object> params, SearchLookup searchLookup);
}

public interface LeafFactory {
StringScriptFieldScript newInstance(LeafReaderContext ctx) throws IOException;
}

private final List<String> results = new ArrayList<>();
private long chars;

public StringScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(params, searchLookup, ctx);
public StringScriptFieldScript(String fieldName, Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) {
super(fieldName, params, searchLookup, ctx);
}

/**
Expand All @@ -49,12 +56,26 @@ public StringScriptFieldScript(Map<String, Object> params, SearchLookup searchLo
*/
public final List<String> resultsForDoc(int docId) {
results.clear();
chars = 0;
setDocument(docId);
execute();
return results;
}

protected final void emitValue(String v) {
checkMaxSize(results.size());
chars += v.length();
if (chars > MAX_CHARS) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"Runtime field [%s] is emitting [%s] characters while the maximum number of values allowed is [%s]",
fieldName,
chars,
MAX_CHARS
)
);
}
results.add(v);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public ScriptBooleanFieldData.Builder fielddataBuilder(String fullyQualifiedInde
}

private BooleanScriptFieldScript.LeafFactory leafFactory(SearchLookup searchLookup) {
return scriptFactory.newFactory(script.getParams(), searchLookup);
return scriptFactory.newFactory(name(), script.getParams(), searchLookup);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public ScriptDateFieldData.Builder fielddataBuilder(String fullyQualifiedIndexNa
}

private DateScriptFieldScript.LeafFactory leafFactory(SearchLookup lookup) {
return scriptFactory.newFactory(script.getParams(), lookup, dateTimeFormatter);
return scriptFactory.newFactory(name(), script.getParams(), lookup, dateTimeFormatter);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public ScriptDoubleFieldData.Builder fielddataBuilder(String fullyQualifiedIndex
}

private DoubleScriptFieldScript.LeafFactory leafFactory(SearchLookup searchLookup) {
return scriptFactory.newFactory(script.getParams(), searchLookup);
return scriptFactory.newFactory(name(), script.getParams(), searchLookup);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public ScriptIpFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName
}

private IpScriptFieldScript.LeafFactory leafFactory(SearchLookup searchLookup) {
return scriptFactory.newFactory(script.getParams(), searchLookup);
return scriptFactory.newFactory(name(), script.getParams(), searchLookup);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public ScriptStringFieldData.Builder fielddataBuilder(String fullyQualifiedIndex
}

private StringScriptFieldScript.LeafFactory leafFactory(SearchLookup searchLookup) {
return scriptFactory.newFactory(script.getParams(), searchLookup);
return scriptFactory.newFactory(name(), script.getParams(), searchLookup);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public ScriptLongFieldData.Builder fielddataBuilder(String fullyQualifiedIndexNa
}

private LongScriptFieldScript.LeafFactory leafFactory(SearchLookup searchLookup) {
return scriptFactory.newFactory(script.getParams(), searchLookup);
return scriptFactory.newFactory(name(), script.getParams(), searchLookup);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import org.elasticsearch.script.ScriptContext;

public class BooleanScriptFieldScriptTests extends ScriptFieldScriptTestCase<BooleanScriptFieldScript.Factory> {
public static final BooleanScriptFieldScript.Factory DUMMY = (params, lookup) -> ctx -> new BooleanScriptFieldScript(
public static final BooleanScriptFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new BooleanScriptFieldScript(
fieldName,
params,
lookup,
ctx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import org.elasticsearch.script.ScriptContext;

public class DateScriptFieldScriptTests extends ScriptFieldScriptTestCase<DateScriptFieldScript.Factory> {
public static final DateScriptFieldScript.Factory DUMMY = (params, lookup, formatter) -> ctx -> new DateScriptFieldScript(
public static final DateScriptFieldScript.Factory DUMMY = (fieldName, params, lookup, formatter) -> ctx -> new DateScriptFieldScript(
fieldName,
params,
lookup,
formatter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import org.elasticsearch.script.ScriptContext;

public class DoubleScriptFieldScriptTests extends ScriptFieldScriptTestCase<DoubleScriptFieldScript.Factory> {
public static final DoubleScriptFieldScript.Factory DUMMY = (params, lookup) -> ctx -> new DoubleScriptFieldScript(
public static final DoubleScriptFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new DoubleScriptFieldScript(
fieldName,
params,
lookup,
ctx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
import org.elasticsearch.script.ScriptContext;

public class IpScriptFieldScriptTests extends ScriptFieldScriptTestCase<IpScriptFieldScript.Factory> {
public static final IpScriptFieldScript.Factory DUMMY = (params, lookup) -> ctx -> new IpScriptFieldScript(params, lookup, ctx) {
public static final IpScriptFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new IpScriptFieldScript(
fieldName,
params,
lookup,
ctx
) {
@Override
public void execute() {
emitValue("192.168.0.1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
import org.elasticsearch.script.ScriptContext;

public class LongScriptFieldScriptTests extends ScriptFieldScriptTestCase<LongScriptFieldScript.Factory> {
public static final LongScriptFieldScript.Factory DUMMY = (params, lookup) -> ctx -> new LongScriptFieldScript(params, lookup, ctx) {
public static final LongScriptFieldScript.Factory DUMMY = (fieldName, params, lookup) -> ctx -> new LongScriptFieldScript(
fieldName,
params,
lookup,
ctx
) {
@Override
public void execute() {
emitValue(1);
Expand Down