Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 52cec25

Browse files
asger-semmleasgerf
authored andcommitted
JS: Build access paths for array accesses
1 parent 5a4be67 commit 52cec25

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

javascript/ql/src/semmle/javascript/GlobalAccessPaths.qll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import javascript
6+
private import semmle.javascript.dataflow.InferredTypes
67

78
deprecated
89
module GlobalAccessPath {
@@ -80,6 +81,35 @@ module AccessPath {
8081
result = base + "." + prop
8182
}
8283

84+
/**
85+
* Holds if `variable` is compared to the `length` property of something, indicating
86+
* that, if used as a dynamic property name, it represents an array index.
87+
*/
88+
private predicate isLikelyArrayIndex(SsaVariable variable) {
89+
exists(RelationalComparison cmp, DataFlow::PropRead length, Expr lengthUse |
90+
length.getPropertyName() = "length" and
91+
length.flowsToExpr(lengthUse) and
92+
cmp.hasOperands(variable.getAUse(), lengthUse)
93+
)
94+
or
95+
isLikelyArrayIndex(variable.getDefinition().(SsaRefinementNode).getAnInput())
96+
}
97+
98+
/**
99+
* Holds if `prop` likely accesses a non-constant array element.
100+
*/
101+
private predicate isLikelyDynamicArrayAccess(DataFlow::PropRead prop) {
102+
// The implicit PropRead in a for-of loop is represented by its lvalue node
103+
prop = DataFlow::lvalueNode(any(ForOfStmt stmt).getLValue())
104+
or
105+
// Match an index access x[i] where `i` is likely an array index variable.
106+
not exists(prop.getPropertyName()) and
107+
exists(SsaVariable indexVar |
108+
isLikelyArrayIndex(indexVar) and
109+
prop.getPropertyNameExpr() = indexVar.getAUse()
110+
)
111+
}
112+
83113
/**
84114
* Gets the access path relative to `root` referred to by `node`.
85115
*
@@ -115,6 +145,9 @@ module AccessPath {
115145
not node.accessesGlobal(_) and
116146
exists(DataFlow::PropRead prop | node = prop |
117147
result = join(fromReference(prop.getBase(), root), prop.getPropertyName())
148+
or
149+
isLikelyDynamicArrayAccess(prop) and
150+
result = join(fromReference(prop.getBase(), root), "[number]")
118151
)
119152
or
120153
exists(Closure::ClosureNamespaceAccess acc | node = acc |

0 commit comments

Comments
 (0)