mirror of
https://github.com/github/codeql.git
synced 2025-12-21 11:16:30 +01:00
Python: Workaround for module level items from import * not being LocalSourceNodes
This commit is contained in:
@@ -11,6 +11,7 @@ import DataFlowPublic
|
|||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
private import semmle.python.internal.Awaited
|
private import semmle.python.internal.Awaited
|
||||||
|
private import semmle.python.dataflow.new.internal.ImportStar
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data flow node that is a source of local flow. This includes things like
|
* A data flow node that is a source of local flow. This includes things like
|
||||||
@@ -39,6 +40,22 @@ class LocalSourceNode extends Node {
|
|||||||
this instanceof ExprNode and
|
this instanceof ExprNode and
|
||||||
not simpleLocalFlowStepForTypetracking(_, this)
|
not simpleLocalFlowStepForTypetracking(_, this)
|
||||||
or
|
or
|
||||||
|
// For `from foo import *; foo_function()`, we want to let the variables we think
|
||||||
|
// could originate in `foo` (such as `foo_function`) to be available in the API
|
||||||
|
// graph. This requires them to be local sources. They would not be from the code
|
||||||
|
// just above, since the CFG node has flow going into it from its corresponding
|
||||||
|
// `GlobalSsaVariable`. (a different work-around is to change API graphs to not rely
|
||||||
|
// as heavily on LocalSourceNode; I initially tried this, but it relied on a lot of
|
||||||
|
// copy-pasted code, and it requires some non-trivial deprecation for downgrading
|
||||||
|
// the result type of `.asSource()` to DataFlow::Node, so we've opted for this
|
||||||
|
// approach instead).
|
||||||
|
//
|
||||||
|
// Note: This is only needed at the module level -- uses inside functions appear as
|
||||||
|
// LocalSourceNodes as we expect.
|
||||||
|
//
|
||||||
|
// TODO: When rewriting SSA, we should be able to remove this workaround
|
||||||
|
ImportStar::namePossiblyDefinedInImportStar(this.(ExprNode).getNode(), _, any(Module m))
|
||||||
|
or
|
||||||
// We include all module variable nodes, as these act as stepping stones between writes and
|
// We include all module variable nodes, as these act as stepping stones between writes and
|
||||||
// reads of global variables. Without them, type tracking based on `LocalSourceNode`s would be
|
// reads of global variables. Without them, type tracking based on `LocalSourceNode`s would be
|
||||||
// unable to track across global variables.
|
// unable to track across global variables.
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
from unknown import * #$ use=moduleImport("unknown")
|
from unknown import * #$ use=moduleImport("unknown")
|
||||||
|
|
||||||
# Currently missing, as we do not consider `hello` to be a `LocalSourceNode`, since it has flow
|
# This used to be missing, as we did not consider `hello` to be a `LocalSourceNode`,
|
||||||
# going into it from its corresponding `GlobalSsaVariable`.
|
# since it has flow going into it from its corresponding `GlobalSsaVariable`.
|
||||||
hello() #$ MISSING: use=moduleImport("unknown").getMember("hello").getReturn()
|
hello() #$ use=moduleImport("unknown").getMember("hello").getReturn()
|
||||||
|
|
||||||
print(const_from_unknown) #$ MISSING: use=moduleImport("unknown").getMember("const_from_unknown")
|
print(const_from_unknown) #$ use=moduleImport("unknown").getMember("const_from_unknown")
|
||||||
|
|
||||||
# We don't want our analysis to think that either `non_module_member` or `outer_bar` can
|
# We don't want our analysis to think that either `non_module_member` or `outer_bar` can
|
||||||
# come from `from unknown import *`
|
# come from `from unknown import *`
|
||||||
|
|||||||
Reference in New Issue
Block a user