mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
39 lines
1.5 KiB
Plaintext
39 lines
1.5 KiB
Plaintext
/**
|
|
* @name Missing exports qualifier
|
|
* @description Referencing an undeclared global variable in a module that exports
|
|
* a definition of the same name is confusing and may indicate a bug.
|
|
* @kind problem
|
|
* @problem.severity error
|
|
* @id js/node/missing-exports-qualifier
|
|
* @tags maintainability
|
|
* frameworks/node.js
|
|
* @precision high
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/** Holds if variable `v` is assigned somewhere in module `m`. */
|
|
predicate definedInModule(GlobalVariable v, NodeModule m) {
|
|
exists(LValue def |
|
|
def.getTopLevel() = m and
|
|
def.(Expr).accessesGlobal(v.getName())
|
|
)
|
|
}
|
|
|
|
from NodeModule m, GlobalVariable f, InvokeExpr invk, DataFlow::Node export, GlobalVarAccess acc
|
|
where
|
|
export = m.getAnExportedValue(f.getName()) and
|
|
acc = f.getAnAccess() and
|
|
invk.getCallee() = acc and
|
|
invk.getTopLevel() = m and
|
|
// don't flag if the variable is defined in the same module
|
|
not definedInModule(f, m) and
|
|
// don't flag if there is a linter directive declaring the variable
|
|
not exists(Linting::GlobalDeclaration glob | glob.declaresGlobalForAccess(acc)) and
|
|
// don't flag if there is an externs declaration for the variable
|
|
not exists(ExternalGlobalDecl egd | egd.getName() = f.getName()) and
|
|
// don't flag if the invocation could refer to a property introduced by `with`
|
|
not exists(WithStmt with | with.mayAffect(invk.getCallee()))
|
|
select invk, "'" + f.getName() + "' references an undeclared global variable, " + "not $@.", export,
|
|
"the variable of the same name that is exported"
|