2025-01-12 20:20:36 +03:00
|
|
|
diff --git a/src/domains/Runtime.ts b/src/domains/Runtime.ts
|
|
|
|
index b980929..67388f9 100644
|
|
|
|
--- a/src/domains/Runtime.ts
|
|
|
|
+++ b/src/domains/Runtime.ts
|
|
|
|
@@ -64,9 +64,9 @@ export function getProperties(
|
|
|
|
return objManager.getProperties(params)
|
|
|
|
}
|
|
|
|
|
|
|
|
-export function evaluate(
|
|
|
|
+export async function evaluate(
|
|
|
|
params: Runtime.EvaluateRequest
|
|
|
|
-): Runtime.EvaluateResponse {
|
|
|
|
+): Promise<Runtime.EvaluateResponse> {
|
|
|
|
const ret: any = {}
|
|
|
|
|
|
|
|
let result: any
|
|
|
|
@@ -74,7 +74,7 @@ export function evaluate(
|
|
|
|
if (params.throwOnSideEffect && hasSideEffect(params.expression)) {
|
|
|
|
throw EvalError('Possible side-effect in debug-evaluate')
|
|
|
|
}
|
|
|
|
- result = evaluateJs(params.expression)
|
|
|
|
+ result = await evaluateJs(params.expression)
|
|
|
|
setGlobal('$_', result)
|
|
|
|
ret.result = objManager.wrap(result, {
|
|
|
|
generatePreview: true,
|
|
|
|
diff --git a/src/index.ts b/src/index.ts
|
|
|
|
index 1dd6e97..0ea8300 100644
|
|
|
|
--- a/src/index.ts
|
|
|
|
+++ b/src/index.ts
|
|
|
|
@@ -38,7 +38,6 @@ chobitsu.register('Runtime', {
|
|
|
|
discardConsoleEntries: noop,
|
|
|
|
getHeapUsage: noop,
|
|
|
|
getIsolateId: noop,
|
|
|
|
- releaseObject: noop,
|
|
|
|
releaseObjectGroup: noop,
|
|
|
|
runIfWaitingForDebugger: noop,
|
|
|
|
})
|
|
|
|
diff --git a/src/lib/evaluate.ts b/src/lib/evaluate.ts
|
2025-01-20 16:38:45 +03:00
|
|
|
index 0732a13..b8f41ae 100644
|
2025-01-12 20:20:36 +03:00
|
|
|
--- a/src/lib/evaluate.ts
|
|
|
|
+++ b/src/lib/evaluate.ts
|
2025-01-20 16:38:45 +03:00
|
|
|
@@ -44,15 +44,34 @@ export function setGlobal(name: string, val: any) {
|
2025-01-12 20:20:36 +03:00
|
|
|
global[name] = val
|
|
|
|
}
|
|
|
|
|
|
|
|
-export default function evaluate(expression: string) {
|
2025-01-20 16:38:45 +03:00
|
|
|
+const createdInEvalIdents: Set<string> = new Set()
|
2025-01-12 20:20:36 +03:00
|
|
|
+export default async function evaluate(expression: string) {
|
|
|
|
let ret
|
|
|
|
|
2025-01-20 16:38:45 +03:00
|
|
|
+ // try to find variables that are declared in the expression
|
|
|
|
+ const vars = expression.match(/(?:;|^|\s)(?:const|let|var)\s+([a-zA-Z0-9_$]+)\s*=/g) ?? []
|
|
|
|
+ let varsInjectScript = ''
|
|
|
|
+ for (const var_ of vars) {
|
|
|
|
+ const name = var_.split(' ')[1].split('=')[0]
|
|
|
|
+ if (name in window && !createdInEvalIdents.has(name)) {
|
|
|
|
+ // avoid overriding existing globals
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ createdInEvalIdents.add(name)
|
|
|
|
+ // todo: we should probably also handle multiple declarations but who even uses that?
|
|
|
|
+ varsInjectScript += `try{window[${JSON.stringify(name)}]=${name}}catch{};`
|
|
|
|
+ }
|
|
|
|
+ if (varsInjectScript) {
|
|
|
|
+ expression += ';' + varsInjectScript
|
|
|
|
+ }
|
2025-01-12 20:20:36 +03:00
|
|
|
injectGlobal()
|
|
|
|
try {
|
|
|
|
- ret = eval.call(window, `(${expression})`)
|
|
|
|
+ ret = await eval.call(window, `(async() => (${expression}))()`)
|
|
|
|
} catch (e) {
|
|
|
|
- ret = eval.call(window, expression)
|
|
|
|
+ ret = await eval.call(window, `(async () => {${expression}})()`)
|
|
|
|
}
|
2025-01-20 16:38:45 +03:00
|
|
|
+
|
2025-01-12 20:20:36 +03:00
|
|
|
clearGlobal()
|
|
|
|
|
2025-01-20 16:38:45 +03:00
|
|
|
return ret
|
2025-01-12 20:20:36 +03:00
|
|
|
diff --git a/src/lib/objManager.ts b/src/lib/objManager.ts
|
|
|
|
index ff6a9e3..d79cdd6 100644
|
|
|
|
--- a/src/lib/objManager.ts
|
|
|
|
+++ b/src/lib/objManager.ts
|
|
|
|
@@ -46,6 +46,10 @@ export function wrap(
|
|
|
|
value: any,
|
|
|
|
{ generatePreview = false, self = value } = {}
|
|
|
|
): any {
|
|
|
|
+ if (typeof value === 'object' && value !== null && typeof value.toJSON === 'function') {
|
|
|
|
+ value = value.toJSON()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
const ret = basic(value)
|
|
|
|
const { type, subtype } = ret
|
|
|
|
|