From cb04e33787e566d8ac66c0e867ddd19484bcaee5 Mon Sep 17 00:00:00 2001 From: adamscybot Date: Sat, 8 Jun 2024 18:33:10 +0100 Subject: [PATCH] Protect `__evaluate_entry` and `__evaluate_exit` callbacks. These two internal APIs are very useful in debugging scenarios, and for imposing time/depth constraints on queries. However, this internal API should only be accessible when configuring an expression programmatically, and not from inside of a query. Otherwise, a query can be manipulated to remove such diagnostics or constraints. By changing both binding keys to Symbol, they can no longer be accessed inside of the query since the Symbol API is not accessible there. --- jsonata.d.ts | 4 ++-- src/jsonata.js | 4 ++-- test/implementation-tests.js | 4 ++-- test/run-test-suite.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jsonata.d.ts b/jsonata.d.ts index 257aac07..0422e22e 100644 --- a/jsonata.d.ts +++ b/jsonata.d.ts @@ -31,8 +31,8 @@ declare namespace jsonata { } interface Environment { - bind(name: string, value: any): void; - lookup(name: string): any; + bind(name: string | symbol, value: any): void; + lookup(name: string | symbol): any; readonly timestamp: Date; readonly async: boolean; } diff --git a/src/jsonata.js b/src/jsonata.js index b7dfad53..19e79643 100644 --- a/src/jsonata.js +++ b/src/jsonata.js @@ -50,7 +50,7 @@ var jsonata = (function() { async function evaluate(expr, input, environment) { var result; - var entryCallback = environment.lookup('__evaluate_entry'); + var entryCallback = environment.lookup(Symbol.for('jsonata.__evaluate_entry')); if(entryCallback) { await entryCallback(expr, input, environment); } @@ -124,7 +124,7 @@ var jsonata = (function() { result = await evaluateGroupExpression(expr.group, result, environment); } - var exitCallback = environment.lookup('__evaluate_exit'); + var exitCallback = environment.lookup(Symbol.for('jsonata.__evaluate_exit')); if(exitCallback) { await exitCallback(expr, input, environment, result); } diff --git a/test/implementation-tests.js b/test/implementation-tests.js index 6df7e679..1e162f6a 100644 --- a/test/implementation-tests.js +++ b/test/implementation-tests.js @@ -1057,11 +1057,11 @@ function timeboxExpression(expr, timeout, maxDepth) { }; // register callbacks - expr.assign("__evaluate_entry", function() { + expr.assign(Symbol.for('jsonata.__evaluate_entry'), function() { depth++; checkRunnaway(); }); - expr.assign("__evaluate_exit", function() { + expr.assign(Symbol.for('jsonata.__evaluate_exit'), function() { depth--; checkRunnaway(); }); diff --git a/test/run-test-suite.js b/test/run-test-suite.js index d851fbf3..60beee05 100644 --- a/test/run-test-suite.js +++ b/test/run-test-suite.js @@ -178,12 +178,12 @@ function timeboxExpression(expr, timeout, maxDepth) { }; // register callbacks - expr.assign("__evaluate_entry", function(expr, input, env) { + expr.assign(Symbol.for('jsonata.__evaluate_entry'), function(expr, input, env) { if (env.isParallelCall) return; depth++; checkRunnaway(); }); - expr.assign("__evaluate_exit", function(expr, input, env) { + expr.assign(Symbol.for('jsonata.__evaluate_exit'), function(expr, input, env) { if (env.isParallelCall) return; depth--; checkRunnaway();