aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/traccar/config/Keys.java22
-rw-r--r--src/main/java/org/traccar/handler/ComputedAttributesHandler.java19
2 files changed, 39 insertions, 2 deletions
diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java
index 093f4298c..6aa41f85b 100644
--- a/src/main/java/org/traccar/config/Keys.java
+++ b/src/main/java/org/traccar/config/Keys.java
@@ -1301,6 +1301,28 @@ public final class Keys {
List.of(KeyType.CONFIG));
/**
+ * Enable local variables declaration.
+ */
+ public static final ConfigKey<Boolean> PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES = new BooleanConfigKey(
+ "processing.computedAttributes.localVariables",
+ List.of(KeyType.CONFIG));
+
+ /**
+ * Enable loops processing.
+ */
+ public static final ConfigKey<Boolean> PROCESSING_COMPUTED_ATTRIBUTES_LOOPS = new BooleanConfigKey(
+ "processing.computedAttributes.loops",
+ List.of(KeyType.CONFIG));
+
+ /**
+ * Enable new instances creation.
+ * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception;
+ */
+ public static final ConfigKey<Boolean> PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION = new BooleanConfigKey(
+ "processing.computedAttributes.newInstanceCreation",
+ List.of(KeyType.CONFIG));
+
+ /**
* Boolean flag to enable or disable reverse geocoder.
*/
public static final ConfigKey<Boolean> GEOCODER_ENABLE = new BooleanConfigKey(
diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java
index ca6c0fc74..e8a4998e3 100644
--- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java
+++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java
@@ -26,8 +26,10 @@ import java.util.Map;
import java.util.Set;
import io.netty.channel.ChannelHandler;
-import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlFeatures;
import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.introspection.JexlSandbox;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.MapContext;
import org.slf4j.Logger;
@@ -53,14 +55,25 @@ public class ComputedAttributesHandler extends BaseDataHandler {
private final JexlEngine engine;
+ private final JexlFeatures features;
+
private final boolean includeDeviceAttributes;
@Inject
public ComputedAttributesHandler(Config config, CacheManager cacheManager) {
this.cacheManager = cacheManager;
+ JexlSandbox sandbox = new JexlSandbox(false);
+ sandbox.allow("com.safe.Functions");
+ sandbox.allow(Math.class.getName());
+ features = new JexlFeatures()
+ .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES))
+ .loops(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS))
+ .newInstance(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION))
+ .structuredLiteral(true);
engine = new JexlBuilder()
.strict(true)
.namespaces(Collections.singletonMap("math", Math.class))
+ .sandbox(sandbox)
.create();
includeDeviceAttributes = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES);
}
@@ -102,7 +115,9 @@ public class ComputedAttributesHandler extends BaseDataHandler {
*/
@Deprecated
public Object computeAttribute(Attribute attribute, Position position) throws JexlException {
- return engine.createExpression(attribute.getExpression()).evaluate(prepareContext(position));
+ return engine.createScript(features,
+ engine.createInfo(),
+ attribute.getExpression()).execute(prepareContext(position));
}
@Override