-
-
-Since JavaScript is a dynamically typed language, module imports in node.js are not statically checked
-for correctness: calls to require
simply return an object containing all the exports of
-the imported module, and accessing a member that was not, in fact, exported, yields
-undefined
. This is most likely unintentional and usually indicates a bug.
-
-
-
-
-
-
-Examine the import in question and determine the correct name of the symbol to import.
-
-
-
-
-
-
-In the following example, module point.js
exports the function Point
by
-assigning it to module.exports
. The client module client.js
tries to
-import it by reading from the Point
property, but since this property does not exist
-the result will be undefined
, and the new
invocation will fail.
-
-
-
-
-
-Instead of reading the Point
property, client.js
should directly use
-the result of the require
call:
-
-
-
-
-
-
-
-
-Node.js Manual: Modules.
-
-
-
-
diff --git a/javascript/ql/src/NodeJS/DubiousImport.ql b/javascript/ql/src/NodeJS/DubiousImport.ql
deleted file mode 100644
index 97ed336e22bc..000000000000
--- a/javascript/ql/src/NodeJS/DubiousImport.ql
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @name Dubious import
- * @description Importing a symbol from a module that does not export it most likely indicates a bug.
- * @kind problem
- * @problem.severity warning
- * @id js/node/import-without-export
- * @tags reliability
- * maintainability
- * frameworks/node.js
- * @precision low
- */
-
-import javascript
-
-/** Holds if `m` is likely to have exports that are not picked up by the analysis. */
-predicate hasUntrackedExports(NodeModule m) {
- // look for assignments of the form `module.exports[p] = ...`, where we cannot
- // determine the name of the exported property being assigned
- exists(DataFlow::PropWrite pwn |
- pwn.getBase().analyze().getAValue() = m.getAModuleExportsValue() and
- not exists(pwn.getPropertyName())
- )
- or
- // look for assignments of the form `module.exports = exp` where `exp` is indefinite
- exists(AbstractModuleObject am, AnalyzedPropertyWrite apw, DataFlow::AnalyzedNode exp |
- am.getModule() = m and
- apw.writes(am, "exports", exp) and
- exp.getAValue().isIndefinite(_)
- )
- or
- // look for function calls of the form `f(module.exports)`
- exists(InvokeExpr invk | invk.getAnArgument().analyze().getAValue() = m.getAModuleExportsValue())
-}
-
-/**
- * Holds if there is an assignment anywhere defining `prop` on the result of
- * a `require` import of module `m`.
- */
-predicate propDefinedOnRequire(NodeModule m, string prop) {
- exists(DataFlow::ModuleImportNode imp |
- imp.asExpr().(Require).getImportedModule() = m and
- exists(imp.getAPropertyWrite(prop))
- )
-}
-
-/**
- * Holds if the base expression of `pacc` could refer to the result of
- * a `require` import of module `m`.
- */
-predicate propAccessOn(PropAccess pacc, NodeModule m) {
- exists(DataFlow::ModuleImportNode imp |
- imp.asExpr().(Require).getImportedModule() = m and
- imp.flowsToExpr(pacc.getBase())
- )
-}
-
-from NodeModule m, PropAccess pacc, string prop
-where
- propAccessOn(pacc, m) and
- count(NodeModule mm | propAccessOn(pacc, mm)) = 1 and
- prop = pacc.getPropertyName() and
- // m doesn't export 'prop'
- not prop = m.getAnExportedSymbol() and
- // 'prop' isn't otherwise defined on m
- not propDefinedOnRequire(m, prop) and
- // m doesn't use complicated exports
- not hasUntrackedExports(m)
-select pacc, "Module $@ does not export symbol " + prop + ".", m, m.getName()
diff --git a/javascript/ql/test/library-tests/NodeJS/tests.expected b/javascript/ql/test/library-tests/NodeJS/tests.expected
index 964b784cf93f..f66d996465ce 100644
--- a/javascript/ql/test/library-tests/NodeJS/tests.expected
+++ b/javascript/ql/test/library-tests/NodeJS/tests.expected
@@ -1,11 +1,3 @@
-module_getAnExportedSymbol
-| b.js:1:1:8:0 |