Skip to content

Commit 47d5287

Browse files
committed
Use a ControlFlowNode based API to determine domination
1 parent 926f2c1 commit 47d5287

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

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

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -436,32 +436,53 @@ module AccessPath {
436436
* Gets the `ranking`th access-path with `root` and `path` within `bb`.
437437
* And the access-path has type `type`.
438438
*/
439-
private DataFlow::Node rankedAccessPath(
439+
private ControlFlowNode rankedAccessPath(
440440
ReachableBasicBlock bb, Root root, string path, int ranking, AccessPathKind type
441441
) {
442442
result =
443-
rank[ranking](DataFlow::Node ref |
443+
rank[ranking](ControlFlowNode ref |
444444
ref = getAccessTo(root, path, _) and
445445
ref.getBasicBlock() = bb
446446
|
447-
ref order by any(int i | ref.asExpr().getEnclosingStmt() = bb.getNode(i))
447+
ref order by any(int i | ref = bb.getNode(i))
448448
) and
449449
result = getAccessTo(root, path, type)
450450
}
451451

452452
/**
453-
* Gets an access to `path` from `root` with type `type`.
453+
* Gets a `ControlFlowNode` for an access to `path` from `root` with type `type`.
454454
*
455455
* This predicate uses both the AccessPath API, and the SourceNode API.
456456
* This ensures that we have basic support for access-paths with ambiguous roots.
457457
*/
458458
pragma[nomagic]
459-
private DataFlow::Node getAccessTo(Root root, string path, AccessPathKind type) {
460-
(path = fromReference(result, root) or result = root.getAPropertyRead(path)) and
461-
type = AccessPathRead()
459+
private ControlFlowNode getAccessTo(Root root, string path, AccessPathKind type) {
460+
type = AccessPathRead() and
461+
result = getAReadNode(root, path)
462462
or
463-
(path = fromRhs(result, root) or result = root.getAPropertyWrite(path).getRhs()) and
464-
type = AccessPathWrite()
463+
type = AccessPathWrite() and
464+
result = getAWriteNode(root, path)
465+
}
466+
467+
/**
468+
* Gets a `ControlFlowNode` for a read to `path` from `root`.
469+
*/
470+
private ControlFlowNode getAReadNode(Root root, string path) {
471+
exists(DataFlow::PropRead read | read.asExpr() = result |
472+
path = fromReference(read, root) or
473+
read = root.getAPropertyRead(path)
474+
)
475+
}
476+
477+
/**
478+
* Gets a `ControlFlowNode` for a write to `path` from `root`.
479+
*/
480+
private ControlFlowNode getAWriteNode(Root root, string path) {
481+
result = root.getAPropertyWrite(path).getWriteNode()
482+
or
483+
exists(DataFlow::PropWrite write | path = fromRhs(write.getRhs(), root) |
484+
result = write.getWriteNode()
485+
)
465486
}
466487

467488
/**
@@ -482,14 +503,14 @@ module AccessPath {
482503
predicate hasDominatingWrite(DataFlow::PropRead read) {
483504
// within the same basic block.
484505
exists(ReachableBasicBlock bb, Root root, string path, int ranking |
485-
read = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and
506+
read.asExpr() = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and
486507
exists(rankedAccessPath(bb, root, path, any(int prev | prev < ranking), AccessPathWrite()))
487508
)
488509
or
489510
// across basic blocks.
490511
exists(Root root, string path |
491-
read = getAccessTo(root, path, AccessPathRead()) and
492-
getAWriteBlock(root, path).strictlyDominates(read.asExpr().getEnclosingStmt().getBasicBlock())
512+
read.asExpr() = getAccessTo(root, path, AccessPathRead()) and
513+
getAWriteBlock(root, path).strictlyDominates(read.getBasicBlock())
493514
)
494515
}
495516
}

0 commit comments

Comments
 (0)