@@ -584,22 +584,26 @@ module TaintTracking {
584584
585585 /**
586586 * A taint propagating data flow edge for assignments of the form `o[k] = v`, where
587- * `k` is not a constant and `o` refers to some object literal; in this case, we consider
588- * taint to flow from `v` to that object literal.
587+ * one of the following holds:
589588 *
590- * The rationale for this heuristic is that if properties of `o` are accessed by
591- * computed (that is, non-constant) names, then `o` is most likely being treated as
592- * a map, not as a real object. In this case, it makes sense to consider the entire
593- * map to be tainted as soon as one of its entries is.
589+ * - `k` is not a constant and `o` refers to some object literal. The rationale
590+ * here is that `o` is most likely being used like a dictionary object.
591+ *
592+ * - `k` refers to `o.length`, that is, the assignment is of form `o[o.length] = v`.
593+ * In this case, the assignment behaves like `o.push(v)`.
594594 */
595- private class DictionaryTaintStep extends SharedTaintStep {
595+ private class ComputedPropWriteTaintStep extends SharedTaintStep {
596596 override predicate heapStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
597- exists ( AssignExpr assgn , IndexExpr idx , DataFlow:: ObjectLiteralNode obj |
597+ exists ( AssignExpr assgn , IndexExpr idx , DataFlow:: SourceNode obj |
598598 assgn .getTarget ( ) = idx and
599599 obj .flowsToExpr ( idx .getBase ( ) ) and
600600 not exists ( idx .getPropertyName ( ) ) and
601601 pred = DataFlow:: valueNode ( assgn .getRhs ( ) ) and
602602 succ = obj
603+ |
604+ obj instanceof DataFlow:: ObjectLiteralNode
605+ or
606+ obj .getAPropertyRead ( "length" ) .flowsToExpr ( idx .getPropertyNameExpr ( ) )
603607 )
604608 }
605609 }
0 commit comments