Skip to content

Commit 8b34551

Browse files
committed
Shared: Add approximate version of getASelected{Source,Sink}Location
1 parent d1b4172 commit 8b34551

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed

shared/dataflow/codeql/dataflow/DataFlow.qll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
459459
*/
460460
default Location getASelectedSourceLocation(Node source) { result = source.getLocation() }
461461

462+
/**
463+
* Like `getASelectedSourceLocation`, but only has to get a location _containing_ the
464+
* actual location associated with `source`.
465+
*
466+
* This prunes fewer sources than `getASelectedSourceLocation` but leaves room for the possibility
467+
* that a more precise location can be selected in the query.
468+
*/
469+
default Location getASelectedSourceLocationApprox(Node source) { none() }
470+
462471
/**
463472
* Gets a location that will be associated with the given `sink` in a
464473
* diff-informed query that uses this configuration (see
@@ -469,6 +478,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
469478
* report the sink at all, this predicate can be `none()`.
470479
*/
471480
default Location getASelectedSinkLocation(Node sink) { result = sink.getLocation() }
481+
482+
/**
483+
* Like `getASelectedSinkLocation`, but only has to get a location _containing_ the
484+
* actual location associated with `sink`.
485+
*
486+
* This prunes fewer sinks than `getASelectedSinkLocation` but leaves room for the possibility
487+
* that a more precise location can be selected in the query.
488+
*/
489+
default Location getASelectedSinkLocationApprox(Node sink) { none() }
472490
}
473491

474492
/** An input configuration for data flow using flow state. */
@@ -608,6 +626,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
608626
*/
609627
default Location getASelectedSourceLocation(Node source) { result = source.getLocation() }
610628

629+
/**
630+
* Like `getASelectedSourceLocation`, but only has to get a location _containing_ the
631+
* actual location associated with `source`.
632+
*
633+
* This prunes fewer sources than `getASelectedSourceLocation` but leaves room for the possibility
634+
* that a more precise location can be selected in the query.
635+
*/
636+
default Location getASelectedSourceLocationApprox(Node source) { none() }
637+
611638
/**
612639
* Gets a location that will be associated with the given `sink` in a
613640
* diff-informed query that uses this configuration (see
@@ -618,6 +645,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
618645
* report the sink at all, this predicate can be `none()`.
619646
*/
620647
default Location getASelectedSinkLocation(Node sink) { result = sink.getLocation() }
648+
649+
/**
650+
* Like `getASelectedSinkLocation`, but only has to get a location _containing_ the
651+
* actual location associated with `sink`.
652+
*
653+
* This prunes fewer sinks than `getASelectedSinkLocation` but leaves room for the possibility
654+
* that a more precise location can be selected in the query.
655+
*/
656+
default Location getASelectedSinkLocationApprox(Node sink) { none() }
621657
}
622658
}
623659

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
145145

146146
Location getASelectedSourceLocation(Node source);
147147

148+
Location getASelectedSourceLocationApprox(Node source);
149+
148150
Location getASelectedSinkLocation(Node sink);
151+
152+
Location getASelectedSinkLocationApprox(Node sink);
149153
}
150154

151155
/**

shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
133133
private predicate isFilteredSource(Node source) {
134134
Config::isSource(source, _) and
135135
if Config::observeDiffInformedIncrementalMode()
136-
then AlertFiltering::filterByLocation(Config::getASelectedSourceLocation(source))
136+
then
137+
AlertFiltering::filterByLocation(Config::getASelectedSourceLocation(source)) or
138+
AlertFiltering::filterByLocationApprox(Config::getASelectedSourceLocationApprox(source))
137139
else any()
138140
}
139141

@@ -144,7 +146,9 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
144146
Config::isSink(sink)
145147
) and
146148
if Config::observeDiffInformedIncrementalMode()
147-
then AlertFiltering::filterByLocation(Config::getASelectedSinkLocation(sink))
149+
then
150+
AlertFiltering::filterByLocation(Config::getASelectedSinkLocation(sink)) or
151+
AlertFiltering::filterByLocationApprox(Config::getASelectedSinkLocationApprox(sink))
148152
else any()
149153
}
150154

shared/util/codeql/util/AlertFiltering.qll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,40 @@ module AlertFilteringImpl<LocationSig Location> {
107107
location.hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn)
108108
)
109109
}
110+
111+
/**
112+
* Holds if some subrange within `location` would be accepted by alert filtering.
113+
*
114+
* There does not need to exist a `Location` corresponding to that subrange.
115+
*/
116+
bindingset[location]
117+
predicate filterByLocationApprox(Location location) {
118+
not restrictAlertsTo(_, _, _) and not restrictAlertsToExactLocation(_, _, _, _, _)
119+
or
120+
exists(string filePath |
121+
restrictAlertsToEntireFile(filePath) and
122+
location.hasLocationInfo(filePath, _, _, _, _)
123+
or
124+
exists(int locStartLine, int locEndLine |
125+
location.hasLocationInfo(filePath, locStartLine, _, locEndLine, _)
126+
|
127+
restrictAlertsToStartLine(filePath, [locStartLine .. locEndLine])
128+
)
129+
)
130+
or
131+
// Check if an exact filter-location is fully contained in `location`.
132+
// This is slow but only used for testing.
133+
exists(
134+
string filePath, int startLine, int startColumn, int endLine, int endColumn,
135+
int filterStartLine, int filterStartColumn, int filterEndLine, int filterEndColumn
136+
|
137+
location.hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn) and
138+
restrictAlertsToExactLocation(filePath, filterStartLine, filterStartColumn, filterEndLine,
139+
filterEndColumn) and
140+
startLine <= filterStartLine and
141+
(startLine != filterStartLine or startColumn <= filterStartColumn) and
142+
endLine >= filterEndLine and
143+
(endLine != filterEndLine or endColumn >= filterEndColumn)
144+
)
145+
}
110146
}

0 commit comments

Comments
 (0)