Skip to content

Commit 0f0187d

Browse files
committed
move Array.from to ArrayCreationNode
1 parent dc4e361 commit 0f0187d

2 files changed

Lines changed: 15 additions & 11 deletions

File tree

javascript/ql/src/semmle/javascript/Arrays.qll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ private module ArrayDataFlow {
219219
*/
220220
private class ArrayCreationStep extends DataFlow::AdditionalFlowStep, DataFlow::Node {
221221
ArrayCreationStep() {
222-
this = DataFlow::globalVarRef("Array").getAPropertyRead("from").getACall() or
223222
this instanceof DataFlow::ArrayCreationNode
224223
}
225224

@@ -228,11 +227,8 @@ private module ArrayDataFlow {
228227
*/
229228
override predicate storeStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
230229
prop = arrayElement() and
231-
succ = this and
232-
(
233-
pred = this.(DataFlow::CallNode).getAnArgument() or
234-
pred = this.(DataFlow::ArrayCreationNode).getAnElement()
235-
)
230+
pred = this.(DataFlow::ArrayCreationNode).getAnElement() and
231+
succ = this
236232
}
237233
}
238234

javascript/ql/src/semmle/javascript/dataflow/Nodes.qll

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,8 @@ class ArrayConstructorInvokeNode extends DataFlow::InvokeNode {
587587
}
588588

589589
/**
590-
* A data flow node corresponding to the creation or a new array, either through an array literal
591-
* or an invocation of the `Array` constructor.
590+
* A data flow node corresponding to the creation or a new array, either through an array literal,
591+
* an invocation of the `Array` constructor, or the `Array.from` method.
592592
*
593593
*
594594
* Examples:
@@ -598,18 +598,23 @@ class ArrayConstructorInvokeNode extends DataFlow::InvokeNode {
598598
* new Array('apple', 'orange')
599599
* Array(16)
600600
* new Array(16)
601+
* Array.from(1,2,3);
601602
* ```
602603
*/
603604
class ArrayCreationNode extends DataFlow::ValueNode, DataFlow::SourceNode {
604605
ArrayCreationNode() {
605606
this instanceof ArrayLiteralNode or
606-
this instanceof ArrayConstructorInvokeNode
607+
this instanceof ArrayConstructorInvokeNode or
608+
this = DataFlow::globalVarRef("Array").getAPropertyRead("from").getACall()
607609
}
608610

609611
/** Gets the `i`th initial element of this array, if one is provided. */
610612
DataFlow::ValueNode getElement(int i) {
611613
result = this.(ArrayLiteralNode).getElement(i) or
612-
result = this.(ArrayConstructorInvokeNode).getElement(i)
614+
result = this.(ArrayConstructorInvokeNode).getElement(i) or
615+
exists(DataFlow::CallNode call | call.getCalleeName() = "from" |
616+
result = call.getArgument(i)
617+
)
613618
}
614619

615620
/** Gets an initial element of this array, if one if provided. */
@@ -618,7 +623,10 @@ class ArrayCreationNode extends DataFlow::ValueNode, DataFlow::SourceNode {
618623
/** Gets the initial size of the created array, if it can be determined. */
619624
int getSize() {
620625
result = this.(ArrayLiteralNode).getSize() or
621-
result = this.(ArrayConstructorInvokeNode).getSize()
626+
result = this.(ArrayConstructorInvokeNode).getSize() or
627+
exists(DataFlow::CallNode call | call.getCalleeName() = "from" |
628+
result = call.getNumArgument()
629+
)
622630
}
623631
}
624632

0 commit comments

Comments
 (0)