Skip to content

Commit 7cb6516

Browse files
committed
make internal predicates within DominatingPaths smaller.
1 parent 1ec2c54 commit 7cb6516

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

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

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,37 +435,70 @@ module AccessPath {
435435
/**
436436
* Gets the `ranking`th access-path with `root` and `path` within `bb`.
437437
* And the access-path has type `type`.
438+
*
439+
* Only has a result if there exists both a read and write of the access-path within `bb`.
438440
*/
439441
private ControlFlowNode rankedAccessPath(
440442
ReachableBasicBlock bb, Root root, string path, int ranking, AccessPathKind type
441443
) {
442444
result =
443445
rank[ranking](ControlFlowNode ref |
444446
ref = getAccessTo(root, path, _) and
445-
ref.getBasicBlock() = bb
447+
ref.getBasicBlock() = bb and
448+
// Prunes the accesses where there does not exists a read and write within the same basicblock.
449+
// This could be more precise, but doing it like this avoids massive joins.
450+
hasRead(bb) and hasWrite(bb)
446451
|
447452
ref order by any(int i | ref = bb.getNode(i))
448453
) and
449454
result = getAccessTo(root, path, type)
450455
}
451456

457+
/**
458+
* Holds if there exists an access-path read inside the basic-block `bb`.
459+
*
460+
* INTERNAL: This predicate is only meant to be used inside `rankedAccessPath`.
461+
*/
462+
pragma[noinline]
463+
private predicate hasRead(ReachableBasicBlock bb) {
464+
bb = getAccessTo(_, _, AccessPathRead()).getBasicBlock()
465+
}
466+
467+
/**
468+
* Holds if there exists an access-path write inside the basic-block `bb`.
469+
*
470+
* INTERNAL: This predicate is only meant to be used inside `rankedAccessPath`.
471+
*/
472+
pragma[noinline]
473+
private predicate hasWrite(ReachableBasicBlock bb) {
474+
bb = getAccessTo(_, _, AccessPathRead()).getBasicBlock()
475+
}
476+
452477
/**
453478
* Gets a `ControlFlowNode` for an access to `path` from `root` with type `type`.
454479
*
455480
* This predicate uses both the AccessPath API, and the SourceNode API.
456481
* This ensures that we have basic support for access-paths with ambiguous roots.
482+
*
483+
* There is only a result if both a read and a write of the access-path exists.
457484
*/
458485
pragma[nomagic]
459486
private ControlFlowNode getAccessTo(Root root, string path, AccessPathKind type) {
460-
type = AccessPathRead() and
461-
result = getAReadNode(root, path)
462-
or
463-
type = AccessPathWrite() and
464-
result = getAWriteNode(root, path)
487+
exists(getAReadNode(root, path)) and
488+
exists(getAWriteNode(root, path)) and
489+
(
490+
type = AccessPathRead() and
491+
result = getAReadNode(root, path)
492+
or
493+
type = AccessPathWrite() and
494+
result = getAWriteNode(root, path)
495+
)
465496
}
466497

467498
/**
468499
* Gets a `ControlFlowNode` for a read to `path` from `root`.
500+
*
501+
* Only used within `getAccessTo`.
469502
*/
470503
private ControlFlowNode getAReadNode(Root root, string path) {
471504
exists(DataFlow::PropRead read | read.asExpr() = result |
@@ -476,6 +509,8 @@ module AccessPath {
476509

477510
/**
478511
* Gets a `ControlFlowNode` for a write to `path` from `root`.
512+
*
513+
* Only used within `getAccessTo`.
479514
*/
480515
private ControlFlowNode getAWriteNode(Root root, string path) {
481516
result = root.getAPropertyWrite(path).getWriteNode()

0 commit comments

Comments
 (0)