diff --git a/test/astdeps.spec.js b/test/astdeps.spec.js index beff1c1e..6cc2cb30 100644 --- a/test/astdeps.spec.js +++ b/test/astdeps.spec.js @@ -1,7 +1,5 @@ // Require Third-party Dependencies import is from "@slimio/is"; - -// Import Third-party Dependencies import test from "tape"; // Require Internal Dependencies diff --git a/test/obfuscated.spec.js b/test/obfuscated.spec.js index 88cbccd3..3efae06f 100644 --- a/test/obfuscated.spec.js +++ b/test/obfuscated.spec.js @@ -1,6 +1,6 @@ // Import Node.js Dependencies -import { readFileSync } from "fs"; -import { fileURLToPath } from "url"; +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; // Import Third-party Dependencies import test from "tape"; diff --git a/test/probes/isAssignmentExpression.spec.js b/test/probes/isAssignmentExpression.spec.js index 31936687..5d460e5b 100644 --- a/test/probes/isAssignmentExpression.spec.js +++ b/test/probes/isAssignmentExpression.spec.js @@ -1,14 +1,15 @@ -// Require Internal Dependencies +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isAssignmentExpression from "../../src/probes/isAssignmentExpression.js"; -// Require Third-party dependencies -import test from "tape"; - test("should detect 1 assignment expression", (tape) => { const str = "obj = { foo: 1 }"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isAssignmentExpression); + const { analysis } = getSastAnalysis(str, isAssignmentExpression) + .execute(ast.body); tape.equal(analysis.idtypes.assignExpr, 1); @@ -18,7 +19,8 @@ test("should detect 1 assignment expression", (tape) => { test("should detect 0 assignment expression", (tape) => { const str = "Object.assign(obj, { foo: 1 })"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isAssignmentExpression); + const { analysis } = getSastAnalysis(str, isAssignmentExpression) + .execute(ast.body); tape.equal(analysis.idtypes.assignExpr, 0); diff --git a/test/probes/isBinaryExpression.spec.js b/test/probes/isBinaryExpression.spec.js index d902a954..0fb56a75 100644 --- a/test/probes/isBinaryExpression.spec.js +++ b/test/probes/isBinaryExpression.spec.js @@ -1,14 +1,15 @@ +// Import Third-party dependencies +import test from "tape"; + // Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isBinaryExpression from "../../src/probes/isBinaryExpression.js"; -// Import Third-party dependencies -import test from "tape"; - test("should detect 1 deep binary expression", (tape) => { const str = "0x1*-0x12df+-0x1fb9*-0x1+0x2*-0x66d"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isBinaryExpression); + const { analysis } = getSastAnalysis(str, isBinaryExpression) + .execute(ast.body); tape.equal(analysis.counter.deepBinaryExpr, 1); @@ -18,7 +19,8 @@ test("should detect 1 deep binary expression", (tape) => { test("should not detect deep binary expression", (tape) => { const str = "10 + 5 - (10)"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isBinaryExpression); + const { analysis } = getSastAnalysis(str, isBinaryExpression) + .execute(ast.body); tape.equal(analysis.counter.deepBinaryExpr, 0); diff --git a/test/probes/isClassDeclaration.spec.js b/test/probes/isClassDeclaration.spec.js index f31c7bd8..18177828 100644 --- a/test/probes/isClassDeclaration.spec.js +++ b/test/probes/isClassDeclaration.spec.js @@ -1,14 +1,15 @@ -// Require Internal Dependencies +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isClassDeclaration from "../../src/probes/isClassDeclaration.js"; -// Require Third-party dependencies -import test from "tape"; - test("should detect two identifiers (class name and superClass name A.K.A extends)", (tape) => { const str = "class File extends Blob {}"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isClassDeclaration); + const { analysis } = getSastAnalysis(str, isClassDeclaration) + .execute(ast.body); tape.deepEqual(analysis.identifiersName, [ { name: "File", type: "class" }, @@ -21,7 +22,8 @@ test("should detect two identifiers (class name and superClass name A.K.A extend test("should detect one identifier because there is no superClass (extension)", (tape) => { const str = "class File {}"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isClassDeclaration); + const { analysis } = getSastAnalysis(str, isClassDeclaration) + .execute(ast.body); tape.deepEqual(analysis.identifiersName, [ { name: "File", type: "class" } @@ -33,7 +35,8 @@ test("should detect one identifier because there is no superClass (extension)", test("should detect one identifier because superClass is not an Identifier but a CallExpression", (tape) => { const str = "class File extends (foo()) {}"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isClassDeclaration); + const { analysis } = getSastAnalysis(str, isClassDeclaration) + .execute(ast.body); tape.deepEqual(analysis.identifiersName, [ { name: "File", type: "class" } diff --git a/test/probes/isFunctionDeclaration.spec.js b/test/probes/isFunctionDeclaration.spec.js index 2e6a12e9..9f8af786 100644 --- a/test/probes/isFunctionDeclaration.spec.js +++ b/test/probes/isFunctionDeclaration.spec.js @@ -1,14 +1,15 @@ -// Require Internal Dependencies +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isFunctionDeclaration from "../../src/probes/isFunctionDeclaration.js"; -// Require Third-party dependencies -import test from "tape"; - test("should detect 1 function declaration", (tape) => { const str = "function foo() {}"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isFunctionDeclaration); + const { analysis } = getSastAnalysis(str, isFunctionDeclaration) + .execute(ast.body); tape.equal(analysis.idtypes.functionDeclaration, 1); @@ -18,7 +19,8 @@ test("should detect 1 function declaration", (tape) => { test("should detect 0 function declaration", (tape) => { const str = "foo()"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isFunctionDeclaration); + const { analysis } = getSastAnalysis(str, isFunctionDeclaration) + .execute(ast.body); tape.equal(analysis.idtypes.functionDeclaration, 0); diff --git a/test/probes/isImportDeclaration.spec.js b/test/probes/isImportDeclaration.spec.js index 6336f2e5..c0e1acc2 100644 --- a/test/probes/isImportDeclaration.spec.js +++ b/test/probes/isImportDeclaration.spec.js @@ -1,14 +1,15 @@ -// Require Internal Dependencies +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isImportDeclaration from "../../src/probes/isImportDeclaration.js"; -// Require Third-party dependencies -import test from "tape"; - test("should detect 1 dependency for an ImportNamespaceSpecifier", (tape) => { const str = "import * as foo from \"bar\""; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isImportDeclaration); + const { analysis } = getSastAnalysis(str, isImportDeclaration) + .execute(ast.body); const { dependencies } = analysis.dependencies; tape.strictEqual("bar" in dependencies, true); @@ -19,7 +20,8 @@ test("should detect 1 dependency for an ImportNamespaceSpecifier", (tape) => { test("should detect 1 dependency for an ImportDefaultSpecifier", (tape) => { const str = "import foo from \"bar\""; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isImportDeclaration); + const { analysis } = getSastAnalysis(str, isImportDeclaration) + .execute(ast.body); const { dependencies } = analysis.dependencies; tape.strictEqual("bar" in dependencies, true); @@ -30,7 +32,8 @@ test("should detect 1 dependency for an ImportDefaultSpecifier", (tape) => { test("should detect 1 dependency for an ImportSpecifier", (tape) => { const str = "import { xd } from \"bar\""; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isImportDeclaration); + const { analysis } = getSastAnalysis(str, isImportDeclaration) + .execute(ast.body); const { dependencies } = analysis.dependencies; tape.strictEqual("bar" in dependencies, true); @@ -41,7 +44,8 @@ test("should detect 1 dependency for an ImportSpecifier", (tape) => { test("should detect 1 dependency with no specificiers", (tape) => { const str = "import \"bar\""; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isImportDeclaration); + const { analysis } = getSastAnalysis(str, isImportDeclaration) + .execute(ast.body); const { dependencies } = analysis.dependencies; tape.strictEqual("bar" in dependencies, true); @@ -54,13 +58,12 @@ test("should detect an unsafe import using data:text/javascript and throw a unsa const str = `import '${expectedValue}';`; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isImportDeclaration); + const sastAnalysis = getSastAnalysis(str, isImportDeclaration) + .execute(ast.body); - const { warnings } = analysis; - tape.strictEqual(warnings.length, 1); + tape.strictEqual(sastAnalysis.warnings().length, 1); - const [unsafeImport] = warnings; - tape.strictEqual(unsafeImport.kind, "unsafe-import"); + const unsafeImport = sastAnalysis.getWarning("unsafe-import"); tape.strictEqual(unsafeImport.value, expectedValue); tape.end(); diff --git a/test/probes/isLiteral.spec.js b/test/probes/isLiteral.spec.js new file mode 100644 index 00000000..c2850a86 --- /dev/null +++ b/test/probes/isLiteral.spec.js @@ -0,0 +1,88 @@ +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies +import { getSastAnalysis, parseScript, mockedFunction } from "../utils/index.js"; +import isLiteral from "../../src/probes/isLiteral.js"; + +test("should throw an unsafe-import because the hexadecimal string is equal to the core 'http' dependency", (tape) => { + const str = "const foo = '68747470'"; + const ast = parseScript(str); + + const analyzeStringMock = mockedFunction(); + const sastAnalysis = getSastAnalysis(str, isLiteral); + sastAnalysis.analysis.analyzeString = analyzeStringMock.callback.bind(analyzeStringMock); + sastAnalysis.execute(ast.body); + + tape.strictEqual(sastAnalysis.warnings().length, 1); + const warning = sastAnalysis.getWarning("unsafe-import"); + tape.strictEqual(warning.kind, "unsafe-import"); + + tape.true("http" in sastAnalysis.dependencies(), true); + tape.true(analyzeStringMock.haveBeenCalledTimes(1)); + tape.true(analyzeStringMock.haveBeenCalledWith("http")); + + tape.end(); +}); + +test("should throw an encoded-literal warning because the hexadecimal value is equal to 'require'", (tape) => { + const str = "const _t = globalThis['72657175697265']"; + const ast = parseScript(str); + + const analyzeStringMock = mockedFunction(); + const sastAnalysis = getSastAnalysis(str, isLiteral); + sastAnalysis.analysis.analyzeString = analyzeStringMock.callback.bind(analyzeStringMock); + sastAnalysis.execute(ast.body); + + tape.strictEqual(sastAnalysis.warnings().length, 1); + const warning = sastAnalysis.getWarning("encoded-literal"); + tape.strictEqual(warning.value, "72657175697265"); + + tape.true(analyzeStringMock.haveBeenCalledTimes(1)); + tape.true(analyzeStringMock.haveBeenCalledWith("require")); + + tape.end(); +}); + +test("should not throw an encoded-literal warning because hexadecimal value is safe", (tape) => { + const str = "const foo = '123456789'"; + const ast = parseScript(str); + const sastAnalysis = getSastAnalysis(str, isLiteral) + .execute(ast.body); + + tape.strictEqual(sastAnalysis.warnings().length, 0); + + tape.end(); +}); + +test("should throw an encoded-literal warning because hexadecimal value is not safe", (tape) => { + // Note: hexadecimal equal 'hello world' + const str = "const foo = '68656c6c6f20776f726c64'"; + const ast = parseScript(str); + const sastAnalysis = getSastAnalysis(str, isLiteral) + .execute(ast.body); + + tape.strictEqual(sastAnalysis.warnings().length, 1); + const warning = sastAnalysis.getWarning("encoded-literal"); + tape.strictEqual(warning.value, "68656c6c6f20776f726c64"); + + tape.end(); +}); + +test("should not throw any warnings without hexadecimal value (and should call analyzeLiteral of Analysis class)", (tape) => { + const str = "const foo = 'hello world!'"; + const ast = parseScript(str); + + const analyzeLiteralMock = mockedFunction(); + const sastAnalysis = getSastAnalysis(str, isLiteral); + sastAnalysis.analysis.analyzeLiteral = analyzeLiteralMock.callback.bind(analyzeLiteralMock); + sastAnalysis.execute(ast.body); + + tape.strictEqual(sastAnalysis.warnings().length, 0); + tape.true(analyzeLiteralMock.haveBeenCalledTimes(1)); + + const astNode = analyzeLiteralMock.args[0]; + tape.strictEqual(astNode.value, "hello world!"); + + tape.end(); +}); diff --git a/test/probes/isLiteralRegex.spec.js b/test/probes/isLiteralRegex.spec.js index cf97dbc3..5c149018 100644 --- a/test/probes/isLiteralRegex.spec.js +++ b/test/probes/isLiteralRegex.spec.js @@ -1,18 +1,19 @@ -// Require Internal Dependencies -import { getSastAnalysis, parseScript, getWarningOnAnalysisResult } from "../utils/index.js"; -import isLiteralRegex from "../../src/probes/isLiteralRegex.js"; - -// Require Third-party dependencies +// Import Third-party dependencies import test from "tape"; +// Import Internal Dependencies +import { getSastAnalysis, parseScript } from "../utils/index.js"; +import isLiteralRegex from "../../src/probes/isLiteralRegex.js"; + test("should throw a 'unsafe-regex' warning because the given RegExp Literal is unsafe", (tape) => { const str = "const foo = /(a+){10}/g;"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isLiteralRegex); + const sastAnalysis = getSastAnalysis(str, isLiteralRegex) + .execute(ast.body); - tape.equal(analysis.warnings.length, 1); - const result = getWarningOnAnalysisResult(analysis, "unsafe-regex"); - tape.equal(result.value, "(a+){10}"); + tape.strictEqual(sastAnalysis.warnings().length, 1); + const result = sastAnalysis.getWarning("unsafe-regex"); + tape.strictEqual(result.value, "(a+){10}"); tape.end(); }); diff --git a/test/probes/isMemberExpression.spec.js b/test/probes/isMemberExpression.spec.js index 80cf9635..aa9f896f 100644 --- a/test/probes/isMemberExpression.spec.js +++ b/test/probes/isMemberExpression.spec.js @@ -1,14 +1,15 @@ -// Require Internal Dependencies +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isMemberExpression from "../../src/probes/isMemberExpression.js"; -// Require Third-party dependencies -import test from "tape"; - test("should detect 1 member expression", (tape) => { const str = "process.mainModule"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isMemberExpression); + const { analysis } = getSastAnalysis(str, isMemberExpression) + .execute(ast.body); tape.equal(analysis.counter.memberExpr, 1); @@ -18,7 +19,8 @@ test("should detect 1 member expression", (tape) => { test("should detect 2 members expressions", (tape) => { const str = "process.mainModule.foo"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isMemberExpression); + const { analysis } = getSastAnalysis(str, isMemberExpression) + .execute(ast.body); tape.equal(analysis.counter.memberExpr, 2); @@ -28,7 +30,8 @@ test("should detect 2 members expressions", (tape) => { test("should detect 1 member expression and 2 nodes", (tape) => { const str = "process.mainModule['foo']['bar']"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isMemberExpression); + const { analysis } = getSastAnalysis(str, isMemberExpression) + .execute(ast.body); tape.equal(analysis.counter.memberExpr, 1); tape.equal(analysis.counter.computedMemberExpr, 2); @@ -39,7 +42,8 @@ test("should detect 1 member expression and 2 nodes", (tape) => { test("should detect 0 member expression", (tape) => { const str = "process"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isMemberExpression); + const { analysis } = getSastAnalysis(str, isMemberExpression) + .execute(ast.body); tape.equal(analysis.counter.memberExpr, 0); diff --git a/test/probes/isMethodDefinition.spec.js b/test/probes/isMethodDefinition.spec.js index 7a9dd236..d7ad4ebd 100644 --- a/test/probes/isMethodDefinition.spec.js +++ b/test/probes/isMethodDefinition.spec.js @@ -1,17 +1,18 @@ -// Require Internal Dependencies +// Import Third-party dependencies +import test from "tape"; + +// Import Internal Dependencies import { getSastAnalysis, parseScript } from "../utils/index.js"; import isMethodDefinition from "../../src/probes/isMethodDefinition.js"; -// Require Third-party dependencies -import test from "tape"; - test("should detect two identifiers (constructor and one method definition)", (tape) => { const str = `class File { constructor() {} foo() {} }`; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isMethodDefinition); + const { analysis } = getSastAnalysis(str, isMethodDefinition) + .execute(ast.body); tape.deepEqual(analysis.identifiersName, [ { name: "constructor", type: "method" }, @@ -27,7 +28,8 @@ test("should detect two identifiers (getter and setter)", (tape) => { set bar(value) {} }`; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isMethodDefinition); + const { analysis } = getSastAnalysis(str, isMethodDefinition) + .execute(ast.body); tape.deepEqual(analysis.identifiersName, [ { name: "foo", type: "method" }, diff --git a/test/probes/isObjectExpression.spec.js b/test/probes/isObjectExpression.spec.js index 944b3434..b8e4df0e 100644 --- a/test/probes/isObjectExpression.spec.js +++ b/test/probes/isObjectExpression.spec.js @@ -1,12 +1,12 @@ -// Require Internal Dependencies -import { getSastAnalysis, parseScript } from "../utils/index.js"; -import isObjectExpression from "../../src/probes/isObjectExpression.js"; +// Import Node.js Dependencies +import { readFileSync } from "node:fs"; -// Require Third-party dependencies +// Import Third-party dependencies import test from "tape"; -// Require Node.js Dependencies -import { readFileSync } from "fs"; +// Import Internal Dependencies +import { getSastAnalysis, parseScript } from "../utils/index.js"; +import isObjectExpression from "../../src/probes/isObjectExpression.js"; // CONSTANTS const FIXTURE_URL = new URL("fixtures/objectExpression/", import.meta.url); @@ -14,7 +14,8 @@ const FIXTURE_URL = new URL("fixtures/objectExpression/", import.meta.url); test("object with 2 properties should have 2 identifiers", (tape) => { const str = readFileSync(new URL("object-objectExpression.js", FIXTURE_URL), "utf-8"); const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isObjectExpression); + const { analysis } = getSastAnalysis(str, isObjectExpression) + .execute(ast.body); tape.equal(analysis.idtypes.property, 2); tape.equal(analysis.identifiersName[0].name, "log"); @@ -25,7 +26,8 @@ test("object with 2 properties should have 2 identifiers", (tape) => { test("class with 2 properties should have 0 identifier", (tape) => { const str = readFileSync(new URL("class-objectExpression.js", FIXTURE_URL), "utf-8"); const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isObjectExpression); + const { analysis } = getSastAnalysis(str, isObjectExpression) + .execute(ast.body); tape.equal(analysis.idtypes.property, 0); tape.equal(analysis.identifiersName.length, 0); diff --git a/test/probes/isRegexObject.spec.js b/test/probes/isRegexObject.spec.js index 3f9e6373..2d9980ed 100644 --- a/test/probes/isRegexObject.spec.js +++ b/test/probes/isRegexObject.spec.js @@ -1,16 +1,17 @@ -// Require Internal Dependencies -import { getSastAnalysis, parseScript, getWarningOnAnalysisResult } from "../utils/index.js"; -import isRegexObject from "../../src/probes/isRegexObject.js"; - -// Require Third-party dependencies +// Import Third-party dependencies import test from "tape"; +// Import Internal Dependencies +import { getSastAnalysis, parseScript } from "../utils/index.js"; +import isRegexObject from "../../src/probes/isRegexObject.js"; + test("should not throw a warning because the given Literal RegExp is considered 'safe'", (tape) => { const str = "const foo = new RegExp('^hello');"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isRegexObject); + const sastAnalysis = getSastAnalysis(str, isRegexObject) + .execute(ast.body); - tape.equal(analysis.warnings.length, 0); + tape.equal(sastAnalysis.warnings().length, 0); tape.end(); }); @@ -18,11 +19,12 @@ test("should not throw a warning because the given Literal RegExp is considered test("should throw a 'unsafe-regex' warning because the given RegExp Object is unsafe", (tape) => { const str = "const foo = new RegExp('(a+){10}');"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isRegexObject); + const sastAnalysis = getSastAnalysis(str, isRegexObject) + .execute(ast.body); - tape.equal(analysis.warnings.length, 1); - const result = getWarningOnAnalysisResult(analysis, "unsafe-regex"); - tape.equal(result.value, "(a+){10}"); + tape.equal(sastAnalysis.warnings().length, 1); + const warning = sastAnalysis.getWarning("unsafe-regex"); + tape.equal(warning.value, "(a+){10}"); tape.end(); }); @@ -30,11 +32,12 @@ test("should throw a 'unsafe-regex' warning because the given RegExp Object is u test("should throw a 'unsafe-regex' warning because the given RegExp Object (with RegExpLiteral) is unsafe", (tape) => { const str = "const foo = new RegExp(/(a+){10}/);"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isRegexObject); + const sastAnalysis = getSastAnalysis(str, isRegexObject) + .execute(ast.body); - tape.equal(analysis.warnings.length, 1); - const result = getWarningOnAnalysisResult(analysis, "unsafe-regex"); - tape.equal(result.value, "(a+){10}"); + tape.equal(sastAnalysis.warnings().length, 1); + const warning = sastAnalysis.getWarning("unsafe-regex"); + tape.equal(warning.value, "(a+){10}"); tape.end(); }); diff --git a/test/probes/isUnsafeCallee.spec.js b/test/probes/isUnsafeCallee.spec.js index ca7f8ba9..88c65345 100644 --- a/test/probes/isUnsafeCallee.spec.js +++ b/test/probes/isUnsafeCallee.spec.js @@ -1,10 +1,10 @@ -// Require Internal Dependencies -import { parseScript, getSastAnalysis, getWarningOnAnalysisResult } from "../utils/index.js"; -import isUnsafeCallee from "../../src/probes/isUnsafeCallee.js"; - -// Require Third-party dependencies +// Import Third-party dependencies import test from "tape"; +// Import Internal Dependencies +import { parseScript, getSastAnalysis } from "../utils/index.js"; +import isUnsafeCallee from "../../src/probes/isUnsafeCallee.js"; + // CONSTANTS const kWarningUnsafeStmt = "unsafe-stmt"; @@ -12,11 +12,13 @@ test("should detect eval", (tape) => { const str = "eval(\"this\");"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isUnsafeCallee); + const sastAnalysis = getSastAnalysis(str, isUnsafeCallee) + .execute(ast.body); - const result = getWarningOnAnalysisResult(analysis, kWarningUnsafeStmt); + const result = sastAnalysis.getWarning(kWarningUnsafeStmt); tape.equal(result.kind, kWarningUnsafeStmt); tape.equal(result.value, "eval"); + tape.end(); }); @@ -24,11 +26,13 @@ test("should detect Function", (tape) => { const str = "Function(\"return this\")()"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isUnsafeCallee); + const sastAnalysis = getSastAnalysis(str, isUnsafeCallee) + .execute(ast.body); - const result = getWarningOnAnalysisResult(analysis, kWarningUnsafeStmt); + const result = sastAnalysis.getWarning(kWarningUnsafeStmt); tape.equal(result.kind, kWarningUnsafeStmt); tape.equal(result.value, "Function"); + tape.end(); }); @@ -36,9 +40,11 @@ test("should not detect Function", (tape) => { const str = "Function('foo');"; const ast = parseScript(str); - const analysis = getSastAnalysis(str, ast.body, isUnsafeCallee); + const sastAnalysis = getSastAnalysis(str, isUnsafeCallee) + .execute(ast.body); - const result = getWarningOnAnalysisResult(analysis, kWarningUnsafeStmt); + const result = sastAnalysis.getWarning(kWarningUnsafeStmt); tape.equal(result, undefined); + tape.end(); }); diff --git a/test/probes/isWeakCrypto.spec.js b/test/probes/isWeakCrypto.spec.js index f326af1f..79d1e258 100644 --- a/test/probes/isWeakCrypto.spec.js +++ b/test/probes/isWeakCrypto.spec.js @@ -1,11 +1,10 @@ -// Node.Js Dependencies -import { readFileSync } from "fs"; -import { readdir } from "fs/promises"; +// Import Node.js Dependencies +import { readFileSync, promises as fs } from "node:fs"; -// Third-party Dependencies +// Import Third-party Dependencies import test from "tape"; -// Internal Dependencies +// Import Internal Dependencies import { runASTAnalysis } from "../../index.js"; // Constants @@ -13,7 +12,7 @@ const FIXTURE_URL = new URL("fixtures/weakCrypto/", import.meta.url); test("it should report a warning in case of `createHash()` usage", async(tape) => { const fixturesDir = new URL("directCallExpression/", FIXTURE_URL); - const fixtureFiles = await readdir(fixturesDir); + const fixtureFiles = await fs.readdir(fixturesDir); for (const fixtureFile of fixtureFiles) { const fixture = readFileSync(new URL(fixtureFile, fixturesDir), "utf-8"); @@ -30,7 +29,7 @@ test("it should report a warning in case of `createHash()` usage", as test("it should report a warning in case of `[expression]createHash()` usage", async(tape) => { const fixturesDir = new URL("memberExpression/", FIXTURE_URL); - const fixtureFiles = await readdir(fixturesDir); + const fixtureFiles = await fs.readdir(fixturesDir); for (const fixtureFile of fixtureFiles) { const fixture = readFileSync(new URL(fixtureFile, fixturesDir), "utf-8"); diff --git a/test/regress.spec.js b/test/regress.spec.js index 022dfc76..5f6a1eac 100644 --- a/test/regress.spec.js +++ b/test/regress.spec.js @@ -1,5 +1,5 @@ // Import Node.js Dependencies -import { readFileSync } from "fs"; +import { readFileSync } from "node:fs"; // Import Third-party Dependencies import test from "tape"; diff --git a/test/searchRuntimeDependencies.spec.js b/test/searchRuntimeDependencies.spec.js index b62e4faa..607054a6 100644 --- a/test/searchRuntimeDependencies.spec.js +++ b/test/searchRuntimeDependencies.spec.js @@ -1,5 +1,5 @@ // Import Node.js Dependencies -import { readFileSync } from "fs"; +import { readFileSync } from "node:fs"; // Import Third-party Dependencies import test from "tape"; diff --git a/test/utils/index.js b/test/utils/index.js index 8390a51a..e043371c 100644 --- a/test/utils/index.js +++ b/test/utils/index.js @@ -6,6 +6,23 @@ export function getWarningKind(warnings) { return warnings.slice().map((warn) => warn.kind).sort(); } +export function mockedFunction() { + return { + called: 0, + args: [], + haveBeenCalledTimes(count = 0) { + return this.called === count; + }, + haveBeenCalledWith(value) { + return this.args.includes(value); + }, + callback(...args) { + this.args.push(...args); + this.called++; + } + }; +} + export function parseScript(str) { return meriyah.parseScript(str, { next: true, @@ -30,29 +47,40 @@ function runOnProbes(node, analysis, probe) { return null; } -export function getSastAnalysis(strSource, body, probe) { - const sastAnalysis = new Analysis(); - sastAnalysis.analyzeSourceString(strSource); +export function getSastAnalysis(strSource, probe) { + return { + analysis: new Analysis(), + getWarning(warning) { + return this.analysis.warnings.find( + (item) => item.kind === warning + ); + }, + warnings() { + return this.analysis.warnings; + }, + dependencies() { + return this.analysis.dependencies.dependencies; + }, + execute(body) { + const self = this; + this.analysis.analyzeSourceString(strSource); - walk(body, { - enter(node) { - // Skip the root of the AST. - if (Array.isArray(node)) { - return; - } + walk(body, { + enter(node) { + // Skip the root of the AST. + if (Array.isArray(node)) { + return; + } + const action = runOnProbes(node, self.analysis, probe); - const action = runOnProbes(node, sastAnalysis, probe); + if (action === "skip") { + this.skip(); + } + } + }); - if (action === "skip") { - this.skip(); - } + return this; } - }); - - return sastAnalysis; -} - -export function getWarningOnAnalysisResult(analysis, warning) { - return analysis.warnings.find((item) => item.kind === warning); + }; } diff --git a/test/warnings.spec.js b/test/warnings.spec.js index 014131b7..345cca70 100644 --- a/test/warnings.spec.js +++ b/test/warnings.spec.js @@ -1,7 +1,7 @@ // Import Third-party Dependencies import test from "tape"; -// Require Internal Dependencies +// Import Internal Dependencies import { rootLocation } from "../src/utils.js"; import { generateWarning } from "../src/warnings.js";