Skip to content

Commit 9f348c3

Browse files
committed
Shared: Add approximate version of getASelected{Source,Sink}Location
1 parent c910c74 commit 9f348c3

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
@@ -457,6 +457,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
457457
*/
458458
default Location getASelectedSourceLocation(Node source) { result = source.getLocation() }
459459

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

472490
/** An input configuration for data flow using flow state. */
@@ -606,6 +624,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
606624
*/
607625
default Location getASelectedSourceLocation(Node source) { result = source.getLocation() }
608626

627+
/**
628+
* Like `getASelectedSourceLocation`, but only has to get a location _containing_ the
629+
* actual location associated with `source`.
630+
*
631+
* This prunes fewer sources than `getASelectedSourceLocation` but leaves room for the possibility
632+
* that a more precise location can be selected in the query.
633+
*/
634+
default Location getASelectedSourceLocationApprox(Node source) { none() }
635+
609636
/**
610637
* Gets a location that will be associated with the given `sink` in a
611638
* diff-informed query that uses this configuration (see
@@ -616,6 +643,15 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
616643
* report the sink at all, this predicate can be `none()`.
617644
*/
618645
default Location getASelectedSinkLocation(Node sink) { result = sink.getLocation() }
646+
647+
/**
648+
* Like `getASelectedSinkLocation`, but only has to get a location _containing_ the
649+
* actual location associated with `sink`.
650+
*
651+
* This prunes fewer sinks than `getASelectedSinkLocation` but leaves room for the possibility
652+
* that a more precise location can be selected in the query.
653+
*/
654+
default Location getASelectedSinkLocationApprox(Node sink) { none() }
619655
}
620656
}
621657

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

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

144144
Location getASelectedSourceLocation(Node source);
145145

146+
Location getASelectedSourceLocationApprox(Node source);
147+
146148
Location getASelectedSinkLocation(Node sink);
149+
150+
Location getASelectedSinkLocationApprox(Node sink);
147151
}
148152

149153
/**

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
131131
private predicate isFilteredSource(Node source) {
132132
Config::isSource(source, _) and
133133
if Config::observeDiffInformedIncrementalMode()
134-
then AlertFiltering::filterByLocation(Config::getASelectedSourceLocation(source))
134+
then
135+
AlertFiltering::filterByLocation(Config::getASelectedSourceLocation(source)) or
136+
AlertFiltering::filterByLocationApprox(Config::getASelectedSourceLocationApprox(source))
135137
else any()
136138
}
137139

@@ -142,7 +144,9 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
142144
Config::isSink(sink)
143145
) and
144146
if Config::observeDiffInformedIncrementalMode()
145-
then AlertFiltering::filterByLocation(Config::getASelectedSinkLocation(sink))
147+
then
148+
AlertFiltering::filterByLocation(Config::getASelectedSinkLocation(sink)) or
149+
AlertFiltering::filterByLocationApprox(Config::getASelectedSinkLocationApprox(sink))
146150
else any()
147151
}
148152

shared/util/codeql/util/AlertFiltering.qll

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

0 commit comments

Comments
 (0)