mirror of
https://github.com/github/codeql.git
synced 2026-04-24 16:25:15 +02:00
JS: Support enumeration through Object.entries
This commit is contained in:
@@ -39,29 +39,13 @@ SourceNode getAnEnumeratedArrayElement(SourceNode array) {
|
||||
* A data flow node that refers to the name of a property obtained by enumerating
|
||||
* the properties of some object.
|
||||
*/
|
||||
class EnumeratedPropName extends DataFlow::Node {
|
||||
DataFlow::Node object;
|
||||
|
||||
EnumeratedPropName() {
|
||||
exists(ForInStmt stmt |
|
||||
this = DataFlow::lvalueNode(stmt.getLValue()) and
|
||||
object = stmt.getIterationDomain().flow()
|
||||
)
|
||||
or
|
||||
exists(CallNode call, string name |
|
||||
call = globalVarRef("Object").getAMemberCall(name) and
|
||||
(name = "keys" or name = "getOwnPropertyNames") and
|
||||
object = call.getArgument(0) and
|
||||
this = getAnEnumeratedArrayElement(call)
|
||||
)
|
||||
}
|
||||
|
||||
abstract class EnumeratedPropName extends DataFlow::Node {
|
||||
/**
|
||||
* Gets the object whose properties are being enumerated.
|
||||
*
|
||||
* For example, gets `src` in `for (var key in src)`.
|
||||
*/
|
||||
Node getSourceObject() { result = object }
|
||||
abstract DataFlow::Node getSourceObject();
|
||||
|
||||
/**
|
||||
* Gets a local reference of the source object.
|
||||
@@ -86,6 +70,53 @@ class EnumeratedPropName extends DataFlow::Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Property enumeration through `for-in` for `Object.keys` or `Object.getOwnPropertyName`.
|
||||
*/
|
||||
class ForInEnumeratedPropName extends EnumeratedPropName {
|
||||
DataFlow::Node object;
|
||||
|
||||
ForInEnumeratedPropName() {
|
||||
exists(ForInStmt stmt |
|
||||
this = DataFlow::lvalueNode(stmt.getLValue()) and
|
||||
object = stmt.getIterationDomain().flow()
|
||||
)
|
||||
or
|
||||
exists(CallNode call, string name |
|
||||
call = globalVarRef("Object").getAMemberCall(name) and
|
||||
(name = "keys" or name = "getOwnPropertyNames") and
|
||||
object = call.getArgument(0) and
|
||||
this = getAnEnumeratedArrayElement(call)
|
||||
)
|
||||
}
|
||||
|
||||
override Node getSourceObject() { result = object }
|
||||
}
|
||||
|
||||
/**
|
||||
* Property enumeration through `Object.entries`.
|
||||
*/
|
||||
class EntriesEnumeratedPropName extends EnumeratedPropName {
|
||||
CallNode entries;
|
||||
SourceNode entry;
|
||||
|
||||
EntriesEnumeratedPropName() {
|
||||
entries = globalVarRef("Object").getAMemberCall("entries") and
|
||||
entry = getAnEnumeratedArrayElement(entries) and
|
||||
this = entry.getAPropertyRead("0")
|
||||
}
|
||||
|
||||
override DataFlow::Node getSourceObject() {
|
||||
result = entries.getArgument(0)
|
||||
}
|
||||
|
||||
override PropRead getASourceProp() {
|
||||
result = super.getASourceProp()
|
||||
or
|
||||
result = entry.getAPropertyRead("1")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the properties of `node` are enumerated locally.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user