Make processStringSync's throw behaviour opt-in.
This commit is contained in:
parent
2e4607edb6
commit
4fb870e449
|
@ -145,10 +145,16 @@
|
|||
const debouncedEval = Utils.debounce((expression, context, snippets) => {
|
||||
try {
|
||||
expressionError = null
|
||||
expressionResult = processStringSync(expression || "", {
|
||||
expressionResult = processStringSync(
|
||||
expression || "",
|
||||
{
|
||||
...context,
|
||||
snippets,
|
||||
})
|
||||
},
|
||||
{
|
||||
noThrow: false,
|
||||
}
|
||||
)
|
||||
} catch (err) {
|
||||
expressionResult = null
|
||||
expressionError = err
|
||||
|
|
|
@ -41,11 +41,11 @@ describe("jsRunner (using isolated-vm)", () => {
|
|||
})
|
||||
|
||||
it("should prevent sandbox escape", async () => {
|
||||
await expect(
|
||||
processJS(`return this.constructor.constructor("return process.env")()`)
|
||||
).rejects.toThrow(
|
||||
"error while running user-supplied JavaScript: ReferenceError: process is not defined"
|
||||
expect(
|
||||
await processJS(
|
||||
`return this.constructor.constructor("return process.env")()`
|
||||
)
|
||||
).toEqual("ReferenceError: process is not defined")
|
||||
})
|
||||
|
||||
describe("helpers", () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AutoFieldDefaultNames } from "../../constants"
|
||||
import { processStringSync, UserScriptError } from "@budibase/string-templates"
|
||||
import { processStringSync } from "@budibase/string-templates"
|
||||
import {
|
||||
AutoColumnFieldMetadata,
|
||||
FieldSchema,
|
||||
|
@ -81,14 +81,7 @@ export async function processFormulas<T extends Row | Row[]>(
|
|||
...row,
|
||||
[column]: tracer.trace("processStringSync", {}, span => {
|
||||
span?.addTags({ table_id: table._id, column, static: isStatic })
|
||||
try {
|
||||
return processStringSync(formula, context)
|
||||
} catch (err: any) {
|
||||
if (err.code === UserScriptError.code) {
|
||||
return err.userScriptError.toString()
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,8 @@ export function processJS(handlebars: string, context: any) {
|
|||
} catch (error: any) {
|
||||
onErrorLog && onErrorLog(error)
|
||||
|
||||
const { noThrow = true } = context.__opts || {}
|
||||
|
||||
// The error handling below is quite messy, because it has fallen to
|
||||
// string-templates to handle a variety of types of error specific to usages
|
||||
// above it in the stack. It would be nice some day to refactor this to
|
||||
|
@ -123,12 +125,18 @@ export function processJS(handlebars: string, context: any) {
|
|||
// This is to catch the error that happens if a user-supplied JS script
|
||||
// throws for reasons introduced by the user.
|
||||
if (error.code === UserScriptError.code) {
|
||||
if (noThrow) {
|
||||
return error.userScriptError.toString()
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
if (error.name === "SyntaxError") {
|
||||
if (noThrow) {
|
||||
return error.toString()
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
return "Error while executing JS"
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ function createTemplate(
|
|||
export async function processObject<T extends Record<string, any>>(
|
||||
object: T,
|
||||
context: object,
|
||||
opts?: { noHelpers?: boolean; escapeNewlines?: boolean; onlyFound?: boolean }
|
||||
opts?: ProcessOptions
|
||||
): Promise<T> {
|
||||
testObject(object)
|
||||
|
||||
|
@ -173,17 +173,13 @@ export async function processString(
|
|||
export function processObjectSync(
|
||||
object: { [x: string]: any },
|
||||
context: any,
|
||||
opts: any
|
||||
opts?: ProcessOptions
|
||||
): object | Array<any> {
|
||||
testObject(object)
|
||||
for (let key of Object.keys(object || {})) {
|
||||
let val = object[key]
|
||||
if (typeof val === "string") {
|
||||
try {
|
||||
object[key] = processStringSync(object[key], context, opts)
|
||||
} catch (error: any) {
|
||||
object[key] = error.toString()
|
||||
}
|
||||
} else if (typeof val === "object") {
|
||||
object[key] = processObjectSync(object[key], context, opts)
|
||||
}
|
||||
|
@ -235,9 +231,6 @@ export function processStringSync(
|
|||
return process(string)
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.code === UserScriptError.code) {
|
||||
throw err
|
||||
}
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ export interface ProcessOptions {
|
|||
noEscaping?: boolean
|
||||
noHelpers?: boolean
|
||||
noFinalise?: boolean
|
||||
noThrow?: boolean
|
||||
escapeNewlines?: boolean
|
||||
onlyFound?: boolean
|
||||
disabledHelpers?: string[]
|
||||
|
|
Loading…
Reference in New Issue