Skip to content

Commit 505c532

Browse files
committed
JS: Implement totalorder()
1 parent 102ca77 commit 505c532

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ class DataFlowCallable extends TDataFlowCallable {
196196

197197
/** Gets the corresponding `LibraryCallable` if this is a library callable. */
198198
LibraryCallable asLibraryCallable() { this = MkLibraryCallable(result) }
199+
200+
int totalorder() {
201+
result = TotalOrdering::astNodeId(this.asSourceCallable()).bitShiftLeft(1)
202+
or
203+
result = TotalOrdering::libraryCallableId(this.asLibraryCallable()).bitShiftLeft(1) + 1
204+
}
199205
}
200206

201207
/** A callable defined in library code, identified by a unique string. */
@@ -456,6 +462,47 @@ private newtype TDataFlowCall =
456462
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
457463
}
458464

465+
private module TotalOrdering {
466+
private predicate astNodeRefl(AstNode x, AstNode y) { x = y }
467+
468+
int astNodeId(AstNode n) = equivalenceRelation(astNodeRefl/2)(n, result)
469+
470+
predicate dataFlowNodeId(DataFlow::Node node, int cls, int content) {
471+
exists(AstNode n |
472+
node = TValueNode(n) and cls = 1 and content = astNodeId(n)
473+
or
474+
node = TReflectiveCallNode(n, _) and cls = 2 and content = astNodeId(n)
475+
)
476+
}
477+
478+
predicate callId(DataFlowCall call, int cls, int child, int extra) {
479+
exists(DataFlow::Node node |
480+
call = MkOrdinaryCall(node) and dataFlowNodeId(node, cls - 1000, child) and extra = 0
481+
or
482+
call = MkPartialCall(node, _) and dataFlowNodeId(node, cls - 2000, child) and extra = 0
483+
or
484+
call = MkBoundCall(node, extra) and dataFlowNodeId(node, cls - 3000, child)
485+
or
486+
call = MkAccessorCall(node) and dataFlowNodeId(node, cls - 4000, child) and extra = 0
487+
)
488+
or
489+
exists(Function f |
490+
call = MkImpliedLambdaCall(f) and cls = 5000 and child = astNodeId(f) and extra = 0
491+
)
492+
or
493+
exists(
494+
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
495+
|
496+
call = MkSummaryCall(c, receiver) and
497+
cls = 6000 and
498+
c = rank[child](FlowSummaryImpl::Public::SummarizedCallable cs) and
499+
extra = 0
500+
)
501+
}
502+
503+
int libraryCallableId(LibraryCallable callable) { callable = rank[result](LibraryCallable c) }
504+
}
505+
459506
class DataFlowCall extends TDataFlowCall {
460507
DataFlowCallable getEnclosingCallable() { none() } // Overridden in subclass
461508

@@ -479,6 +526,15 @@ class DataFlowCall extends TDataFlowCall {
479526
}
480527

481528
Location getLocation() { none() } // Overridden in subclass
529+
530+
int totalorder() {
531+
this =
532+
rank[result](DataFlowCall call, int x, int y, int z |
533+
TotalOrdering::callId(call, x, y, z)
534+
|
535+
call order by x, y, z
536+
)
537+
}
482538
}
483539

484540
private class OrdinaryCall extends DataFlowCall, MkOrdinaryCall {

0 commit comments

Comments
 (0)