Fix Nashorn sandbox script compile error (ScriptCPUAbuseException)
This commit is contained in:
parent
e62665bdcd
commit
f34361e1ea
@ -39,12 +39,13 @@ import java.util.concurrent.TimeoutException;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.thingsboard.server.common.data.msg.TbMsgType.POST_TELEMETRY_REQUEST;
|
import static org.thingsboard.server.common.data.msg.TbMsgType.POST_TELEMETRY_REQUEST;
|
||||||
|
|
||||||
@DaoSqlTest
|
@DaoSqlTest
|
||||||
@TestPropertySource(properties = {
|
@TestPropertySource(properties = {
|
||||||
"js.evaluator=local",
|
"js.evaluator=local",
|
||||||
"js.max_script_body_size=50",
|
"js.max_script_body_size=10000",
|
||||||
"js.max_total_args_size=50",
|
"js.max_total_args_size=50",
|
||||||
"js.max_result_size=50",
|
"js.max_result_size=50",
|
||||||
"js.local.max_errors=2",
|
"js.local.max_errors=2",
|
||||||
@ -87,7 +88,7 @@ class NashornJsInvokeServiceTest extends AbstractControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void givenSimpleScriptMultiThreadTestPerformance() throws ExecutionException, InterruptedException, TimeoutException {
|
void givenSimpleScriptMultiThreadTestPerformance() throws ExecutionException, InterruptedException, TimeoutException {
|
||||||
int iterations = 1000*4;
|
int iterations = 1000 * 4;
|
||||||
List<ListenableFuture<Object>> futures = new ArrayList<>(iterations);
|
List<ListenableFuture<Object>> futures = new ArrayList<>(iterations);
|
||||||
UUID scriptId = evalScript("return msg.temperature > 20 ;");
|
UUID scriptId = evalScript("return msg.temperature > 20 ;");
|
||||||
// warmup
|
// warmup
|
||||||
@ -125,7 +126,7 @@ class NashornJsInvokeServiceTest extends AbstractControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void givenTooBigScriptForEval_thenReturnError() {
|
void givenTooBigScriptForEval_thenReturnError() {
|
||||||
String hugeScript = "var a = 'qwertyqwertywertyqwabababer'; return {a: a};";
|
String hugeScript = "var a = '" + "a".repeat(10000) + "'; return {a: a};";
|
||||||
|
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> {
|
||||||
evalScript(hugeScript);
|
evalScript(hugeScript);
|
||||||
@ -159,6 +160,46 @@ class NashornJsInvokeServiceTest extends AbstractControllerTest {
|
|||||||
assertThatScriptIsBlocked(scriptId);
|
assertThatScriptIsBlocked(scriptId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenComplexScript_testCompile() {
|
||||||
|
String script = """
|
||||||
|
function(data) {
|
||||||
|
if (data.get("propertyA") == "a special value 1" || data.get("propertyA") == "a special value 2") {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyC") == "a special value 1" || data.get("propertyJ") == "a special value 1" || data.get("propertyV") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "4" && (data.get("propertyD") == "a special value 1" || data.get("propertyV") == "a special value 1" || data.get("propertyW") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 2" && (data.get("propertyE") == "a special value 1" || data.get("propertyF") == "a special value 1" || data.get("propertyL") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyE") == "a special value 1" || data.get("propertyF") == "a special value 1" || data.get("propertyL") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else if (data.get("propertyB") == "a special value 3" && (data.get("propertyM") == "a special value 1" || data.get("propertyY") == "a special value 1" || data.get("propertyH") == "a special value 1")) {
|
||||||
|
return "a special value 1";
|
||||||
|
} else {
|
||||||
|
return "0"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
// with delight-nashorn-sandbox 0.4.2, this would throw delight.nashornsandbox.exceptions.ScriptCPUAbuseException: Regular expression running for too many iterations. The operation could NOT be gracefully interrupted.
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
evalScript(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void assertThatScriptIsBlocked(UUID scriptId) {
|
private void assertThatScriptIsBlocked(UUID scriptId) {
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> {
|
||||||
invokeScript(scriptId, "{}");
|
invokeScript(scriptId, "{}");
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@ -105,7 +105,7 @@
|
|||||||
org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/*
|
org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/*
|
||||||
</sonar.exclusions>
|
</sonar.exclusions>
|
||||||
<elasticsearch.version>8.13.2</elasticsearch.version>
|
<elasticsearch.version>8.13.2</elasticsearch.version>
|
||||||
<delight-nashorn-sandbox.version>0.4.2</delight-nashorn-sandbox.version>
|
<delight-nashorn-sandbox.version>0.4.5</delight-nashorn-sandbox.version>
|
||||||
<nashorn-core.version>15.4</nashorn-core.version>
|
<nashorn-core.version>15.4</nashorn-core.version>
|
||||||
<!-- IMPORTANT: If you change the version of the kafka client, make sure to synchronize our overwritten implementation of the
|
<!-- IMPORTANT: If you change the version of the kafka client, make sure to synchronize our overwritten implementation of the
|
||||||
org.apache.kafka.common.network.NetworkReceive class in the application module. It addresses the issue https://issues.apache.org/jira/browse/KAFKA-4090.
|
org.apache.kafka.common.network.NetworkReceive class in the application module. It addresses the issue https://issues.apache.org/jira/browse/KAFKA-4090.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user