mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
71 lines
2.2 KiB
Plaintext
71 lines
2.2 KiB
Plaintext
/**
|
|
* @name Missing variable declaration
|
|
* @description If a variable is not declared as a local variable, it becomes a global variable
|
|
* by default, which may be unintentional and could lead to unexpected behavior.
|
|
* @kind problem
|
|
* @problem.severity warning
|
|
* @id js/missing-variable-declaration
|
|
* @tags reliability
|
|
* maintainability
|
|
* @precision high
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Gets an undeclared global in `f`, that is, a global variable that is accessed in `f`,
|
|
* but not declared in the same toplevel as `f`.
|
|
*/
|
|
GlobalVariable undeclaredGlobalIn(Function f) {
|
|
exists(GlobalVarAccess gva | gva = result.getAnAccess() |
|
|
gva.getEnclosingFunction() = f and
|
|
not result.declaredIn(f.getTopLevel()) and
|
|
not exists(Linting::GlobalDeclaration gd | gd.declaresGlobalForAccess(gva))
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Gets an accidental global in `f`, that is, an undeclared global in `f` that is not
|
|
* live at the entry of `f`, meaning that it is always written before being read the
|
|
* first time.
|
|
*/
|
|
GlobalVariable accidentalGlobalIn(Function f) {
|
|
result = undeclaredGlobalIn(f) and
|
|
exists(BasicBlock startBB | startBB = f.getStartBB() | not startBB.isLiveAtEntry(result))
|
|
}
|
|
|
|
/**
|
|
* Gets an accidental global in `f` that is read at least once in reachable code.
|
|
*
|
|
* This prevents duplication of results between this query and 'Useless assignment
|
|
* to global variable'.
|
|
*/
|
|
GlobalVariable candidateVariable(Function f) {
|
|
result = accidentalGlobalIn(f) and
|
|
f.getStartBB().getASuccessor*().useAt(_, result, _)
|
|
}
|
|
|
|
/**
|
|
* Gets an access to `v` in function `f`.
|
|
*/
|
|
GlobalVarAccess getAccessIn(GlobalVariable v, Function f) {
|
|
result.getEnclosingFunction() = f and
|
|
result = v.getAnAccess()
|
|
}
|
|
|
|
/**
|
|
* Gets the (lexically) first access to variable `v` in function `f`.
|
|
*/
|
|
GlobalVarAccess getFirstAccessIn(GlobalVariable v, Function f) {
|
|
result =
|
|
min(getAccessIn(v, f) as gva
|
|
order by
|
|
gva.getLocation().getStartLine(), gva.getLocation().getStartColumn()
|
|
)
|
|
}
|
|
|
|
from Function f, GlobalVariable gv
|
|
where gv = candidateVariable(f)
|
|
select getFirstAccessIn(gv, f),
|
|
"Variable " + gv.getName() + " is used like a local variable, but is missing a declaration."
|