mirror of
https://github.com/github/codeql.git
synced 2026-05-05 05:35:13 +02:00
JS: Simplify call graph metric
This commit is contained in:
@@ -47,97 +47,6 @@ class RelevantFunction extends Function {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `name` is a the name of an external module.
|
||||
*/
|
||||
predicate isExternalLibrary(string name) {
|
||||
// Mentioned in package.json
|
||||
any(Dependency dep).info(name, _) or
|
||||
// Node.js built-in
|
||||
name = "assert" or
|
||||
name = "async_hooks" or
|
||||
name = "child_process" or
|
||||
name = "cluster" or
|
||||
name = "crypto" or
|
||||
name = "dns" or
|
||||
name = "domain" or
|
||||
name = "events" or
|
||||
name = "fs" or
|
||||
name = "http" or
|
||||
name = "http2" or
|
||||
name = "https" or
|
||||
name = "inspector" or
|
||||
name = "net" or
|
||||
name = "os" or
|
||||
name = "path" or
|
||||
name = "perf_hooks" or
|
||||
name = "process" or
|
||||
name = "punycode" or
|
||||
name = "querystring" or
|
||||
name = "readline" or
|
||||
name = "repl" or
|
||||
name = "stream" or
|
||||
name = "string_decoder" or
|
||||
name = "timer" or
|
||||
name = "tls" or
|
||||
name = "trace_events" or
|
||||
name = "tty" or
|
||||
name = "dgram" or
|
||||
name = "url" or
|
||||
name = "util" or
|
||||
name = "v8" or
|
||||
name = "vm" or
|
||||
name = "worker_threads" or
|
||||
name = "zlib"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the global variable `name` is defined externally.
|
||||
*/
|
||||
predicate isExternalGlobal(string name) {
|
||||
exists(ExternalGlobalDecl decl | decl.getName() = name)
|
||||
or
|
||||
exists(Dependency dep |
|
||||
// If name is never assigned anywhere, and it coincides with a dependency,
|
||||
// it's most likely coming from there.
|
||||
dep.info(name, _) and
|
||||
not exists(Assignment assign | assign.getLhs().(GlobalVarAccess).getName() = name)
|
||||
)
|
||||
or
|
||||
name = "_"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node that was derived from an import of `moduleName`.
|
||||
*
|
||||
* This is a rough approximation as it follows all property reads, invocations,
|
||||
* and callbacks, so some of these might refer to internal objects.
|
||||
*
|
||||
* Additionally, we don't recognize when a project imports another file in the
|
||||
* same project using its module name (for example import "vscode" from inside the vscode project).
|
||||
*/
|
||||
SourceNode externalNode() {
|
||||
exists(string moduleName |
|
||||
result = moduleImport(moduleName) and
|
||||
isExternalLibrary(moduleName)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
result = globalVarRef(name) and
|
||||
isExternalGlobal(name)
|
||||
)
|
||||
or
|
||||
result = DOM::domValueRef()
|
||||
or
|
||||
result = jquery()
|
||||
or
|
||||
result = externalNode().getAPropertyRead()
|
||||
or
|
||||
result = externalNode().getAnInvocation()
|
||||
or
|
||||
result = externalNode().(InvokeNode).getCallback(_).getParameter(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a data flow node that can be resolved to a function, usually a callback.
|
||||
*
|
||||
@@ -192,49 +101,15 @@ class ResolvableCall extends RelevantInvoke {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call site that is believed to call an external function.
|
||||
*/
|
||||
class ExternalCall extends RelevantInvoke {
|
||||
ExternalCall() {
|
||||
not this instanceof ResolvableCall and // avoid double counting
|
||||
(
|
||||
// Call to modelled external library
|
||||
this = externalNode()
|
||||
or
|
||||
// 'require' call or similar
|
||||
this = moduleImport(_)
|
||||
or
|
||||
// Resolved to externs file
|
||||
exists(this.(InvokeNode).getACallee(1))
|
||||
or
|
||||
// Modelled as taint step but isn't from an NPM module, for example, `substring` or `push`.
|
||||
exists(TaintTracking::AdditionalTaintStep step |
|
||||
step.step(_, this)
|
||||
or
|
||||
step.step(this.getAnArgument(), _)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call site that could not be resolved.
|
||||
*/
|
||||
class UnresolvableCall extends RelevantInvoke {
|
||||
UnresolvableCall() {
|
||||
not this instanceof ResolvableCall and
|
||||
not this instanceof ExternalCall
|
||||
not this instanceof ResolvableCall
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that is believed to call a function within the same project.
|
||||
*/
|
||||
class NonExternalCall extends RelevantInvoke {
|
||||
NonExternalCall() { not this instanceof ExternalCall }
|
||||
}
|
||||
|
||||
/**
|
||||
* A function with at least one call site.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user