JS: Add OptionalStep and OptionalBarrier MaD tokens

OptionalStep[foo] and OptionalBarrier[foo] contribute steps/barriers that are not active by default, but can be opted into by specific queries or for specific flow states.

(Will be used in the following commits)
This commit is contained in:
Asger F
2024-09-10 14:59:39 +02:00
parent 87454a4f11
commit 24983a5836
3 changed files with 44 additions and 2 deletions

View File

@@ -93,14 +93,20 @@ module Private {
// than an ordinary content component. These special content sets should never appear in a step.
MkAwaited() or
MkAnyPropertyDeep() or
MkArrayElementDeep()
MkArrayElementDeep() or
MkOptionalStep(string name) { isAccessPathTokenPresent("OptionalStep", name) } or
MkOptionalBarrier(string name) { isAccessPathTokenPresent("OptionalBarrier", name) }
/**
* Holds if `cs` is used to encode a special operation as a content component, but should not
* be treated as an ordinary content component.
*/
predicate isSpecialContentSet(ContentSet cs) {
cs = MkAwaited() or cs = MkAnyPropertyDeep() or cs = MkArrayElementDeep()
cs = MkAwaited() or
cs = MkAnyPropertyDeep() or
cs = MkArrayElementDeep() or
cs instanceof MkOptionalStep or
cs instanceof MkOptionalBarrier
}
}
@@ -288,6 +294,16 @@ module Public {
or
this = MkAnyCapturedContent() and
result = "AnyCapturedContent"
or
exists(string name |
this = MkOptionalStep(name) and
result = "OptionalStep[" + name + "]"
)
or
exists(string name |
this = MkOptionalBarrier(name) and
result = "OptionalBarrier[" + name + "]"
)
}
}

View File

@@ -1035,6 +1035,11 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
FlowSummaryPrivate::Steps::summaryReadStep(input, MkAwaited(), output) and
node1 = TFlowSummaryNode(input) and
node2 = TFlowSummaryNode(output)
or
// Add flow through optional barriers. This step is then blocked by the barrier for queries that choose to use the barrier.
FlowSummaryPrivate::Steps::summaryReadStep(input, MkOptionalBarrier(_), output) and
node1 = TFlowSummaryNode(input) and
node2 = TFlowSummaryNode(output)
)
or
VariableCaptureOutput::localFlowStep(getClosureNode(node1), getClosureNode(node2))
@@ -1389,3 +1394,20 @@ class ArgumentNode extends DataFlow::Node {
class ParameterNode extends DataFlow::Node {
ParameterNode() { isParameterNodeImpl(this, _, _) }
}
cached
private module OptionalSteps {
cached
predicate optionalStep(Node node1, string name, Node node2) {
FlowSummaryPrivate::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(),
MkOptionalStep(name), node2.(FlowSummaryNode).getSummaryNode())
}
cached
predicate optionalBarrier(Node node, string name) {
FlowSummaryPrivate::Steps::summaryReadStep(_, MkOptionalBarrier(name),
node.(FlowSummaryNode).getSummaryNode())
}
}
import OptionalSteps

View File

@@ -95,6 +95,10 @@ private string encodeContentAux(ContentSet cs, string arg) {
cs = MkAnyPropertyDeep() and result = "AnyMemberDeep" and arg = ""
or
cs = MkArrayElementDeep() and result = "ArrayElementDeep" and arg = ""
or
cs = MkOptionalStep(arg) and result = "OptionalStep"
or
cs = MkOptionalBarrier(arg) and result = "OptionalBarrier"
}
/**