fix: boolean, undefined, null values eval in quickjs vm (#2893)

fix: boolean, undeifned, null values in pre-request vars
This commit is contained in:
lohit 2024-08-23 16:18:41 +05:30 committed by GitHub
parent 4d55b50250
commit 44d70ca02a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 107 additions and 6 deletions

View File

@ -66,7 +66,9 @@ if (!SERVER_RENDERED) {
'bru.getVar(key)', 'bru.getVar(key)',
'bru.setVar(key,value)', 'bru.setVar(key,value)',
'bru.deleteVar(key)', 'bru.deleteVar(key)',
'bru.setNextRequest(requestName)' 'bru.setNextRequest(requestName)',
'bru.getRequestVar(key)',
'bru.sleep(ms)'
]; ];
CodeMirror.registerHelper('hint', 'brunoJS', (editor, options) => { CodeMirror.registerHelper('hint', 'brunoJS', (editor, options) => {
const cursor = editor.getCursor(); const cursor = editor.getCursor();

View File

@ -6,7 +6,7 @@ import Portal from 'components/Portal';
import Modal from 'components/Modal'; import Modal from 'components/Modal';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
const JsSandboxModeModal = ({ collection, onClose }) => { const JsSandboxModeModal = ({ collection }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [jsSandboxMode, setJsSandboxMode] = useState(collection?.securityConfig?.jsSandboxMode || 'safe'); const [jsSandboxMode, setJsSandboxMode] = useState(collection?.securityConfig?.jsSandboxMode || 'safe');
@ -22,7 +22,6 @@ const JsSandboxModeModal = ({ collection, onClose }) => {
) )
.then(() => { .then(() => {
toast.success('Sandbox mode updated successfully'); toast.success('Sandbox mode updated successfully');
onClose();
}) })
.catch((err) => console.log(err) && toast.error('Failed to update sandbox mode')); .catch((err) => console.log(err) && toast.error('Failed to update sandbox mode'));
}; };

View File

@ -14,7 +14,7 @@
"url": "git+https://github.com/usebruno/bruno.git" "url": "git+https://github.com/usebruno/bruno.git"
}, },
"scripts": { "scripts": {
"test": "node --experimental-vm-modules $(npx --no-install which jest)" "test": "node --experimental-vm-modules $(npx which jest)"
}, },
"files": [ "files": [
"src", "src",

View File

@ -16,7 +16,7 @@
"dist:rpm": "electron-builder --linux rpm --config electron-builder-config.js", "dist:rpm": "electron-builder --linux rpm --config electron-builder-config.js",
"dist:snap": "electron-builder --linux snap --config electron-builder-config.js", "dist:snap": "electron-builder --linux snap --config electron-builder-config.js",
"pack": "electron-builder --dir", "pack": "electron-builder --dir",
"test": "node --experimental-vm-modules $(npx --no-install which jest)" "test": "node --experimental-vm-modules $(npx which jest)"
}, },
"jest": { "jest": {
"modulePaths": ["node_modules"] "modulePaths": ["node_modules"]

View File

@ -11,7 +11,7 @@
"@n8n/vm2": "^3.9.23" "@n8n/vm2": "^3.9.23"
}, },
"scripts": { "scripts": {
"test": "node --experimental-vm-modules $(npx --no-install which jest) --testPathIgnorePatterns test.js", "test": "node --experimental-vm-modules $(npx which jest) --testPathIgnorePatterns test.js",
"sandbox:bundle-libraries": "node ./src/sandbox/bundle-libraries.js" "sandbox:bundle-libraries": "node ./src/sandbox/bundle-libraries.js"
}, },
"dependencies": { "dependencies": {

View File

@ -21,11 +21,30 @@ const toNumber = (value) => {
return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value); return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value);
}; };
const removeQuotes = (str) => {
if ((str.startsWith('"') && str.endsWith('"')) || (str.startsWith("'") && str.endsWith("'"))) {
return str.slice(1, -1);
}
return str;
};
const executeQuickJsVm = ({ script: externalScript, context: externalContext, scriptType = 'template-literal' }) => { const executeQuickJsVm = ({ script: externalScript, context: externalContext, scriptType = 'template-literal' }) => {
if (!externalScript?.length || typeof externalScript !== 'string') {
return externalScript;
}
externalScript = externalScript?.trim();
if (!isNaN(Number(externalScript))) { if (!isNaN(Number(externalScript))) {
return Number(externalScript); return Number(externalScript);
} }
if (externalScript === 'true') return true;
if (externalScript === 'false') return false;
if (externalScript === 'null') return null;
if (externalScript === 'undefined') return undefined;
externalScript = removeQuotes(externalScript);
const vm = QuickJSSyncContext; const vm = QuickJSSyncContext;
try { try {
@ -57,9 +76,22 @@ const executeQuickJsVm = ({ script: externalScript, context: externalContext, sc
}; };
const executeQuickJsVmAsync = async ({ script: externalScript, context: externalContext, collectionPath }) => { const executeQuickJsVmAsync = async ({ script: externalScript, context: externalContext, collectionPath }) => {
if (!externalScript?.length || typeof externalScript !== 'string') {
return externalScript;
}
externalScript = externalScript?.trim();
if (!isNaN(Number(externalScript))) { if (!isNaN(Number(externalScript))) {
return toNumber(externalScript); return toNumber(externalScript);
} }
if (externalScript === 'true') return true;
if (externalScript === 'false') return false;
if (externalScript === 'null') return null;
if (externalScript === 'undefined') return undefined;
externalScript = removeQuotes(externalScript);
try { try {
const module = await newQuickJSWASMModule(); const module = await newQuickJSWASMModule();
const vm = module.newContext(); const vm = module.newContext();

View File

@ -0,0 +1,68 @@
meta {
name: data types - request vars
type: http
seq: 3
}
post {
url: {{host}}/api/echo/json
body: json
auth: none
}
body:json {
{
"boolean": false,
"number": 1,
"string": "bruno",
"array": [1, 2, 3, 4, 5],
"object": {
"hello": "bruno"
},
"null": null
}
}
vars:pre-request {
number: 1
boolean: false
undefined: undefined
null: null
string: foo
}
assert {
req.body.boolean: isBoolean false
req.body.number: isNumber 1
req.body.undefined: isUndefined undefined
req.body.string: isString bruno
req.body.null: isNull null
req.body.array: isArray
req.body.boolean: eq false
req.body.number: eq 1
req.body.undefined: eq undefined
req.body.string: eq bruno
req.body.null: eq null
}
tests {
test("boolean pre var", function() {
expect(bru.getRequestVar('boolean')).to.eql(false);
});
test("number pre var", function() {
expect(bru.getRequestVar('number')).to.eql(1);
});
test("null pre var", function() {
expect(bru.getRequestVar('null')).to.eql(null);
});
test("undefined pre var", function() {
expect(bru.getRequestVar('undefined')).to.eql(undefined);
});
test("string pre var", function() {
expect(bru.getRequestVar('string')).to.eql('foo');
});
}