Skip to content

Commit f3ef851

Browse files
authored
Merge pull request #10093 from smowton/smowton/feature/java-singular-locations
Java: pick an arbitrary representative location when an entity has many candidate locations.
2 parents 04564b4 + 8d20b9c commit f3ef851

File tree

11 files changed

+131
-18
lines changed

11 files changed

+131
-18
lines changed

cpp/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}

csharp/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}

go/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Classes and methods that are seen with several different paths during the extraction process (for example, packaged into different JAR files) now report an arbitrarily selected location via their `getLocation` and `hasLocationInfo` predicates, rather than reporting all of them. This may lead to reduced alert duplication.

java/ql/lib/semmle/code/Location.qll

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,19 @@ cached
205205
private predicate fixedHasLocation(Top l, Location loc, File f) {
206206
hasSourceLocation(l, loc, f)
207207
or
208-
hasLocation(l, loc) and not hasSourceLocation(l, _, _) and locations_default(loc, f, _, _, _, _)
208+
// When an entity has more than one location, as it might due to
209+
// e.g. a parameterized generic being seen and extracted in several
210+
// different directories or JAR files, select an arbitrary representative
211+
// location to avoid needlessly duplicating alerts.
212+
//
213+
// Don't do this when the relevant location is in a source file, because
214+
// that is much more unusual and we would rather notice the bug than mask it here.
215+
loc =
216+
min(Location candidateLoc |
217+
hasLocation(l, candidateLoc)
218+
|
219+
candidateLoc order by candidateLoc.getFile().toString()
220+
) and
221+
not hasSourceLocation(l, _, _) and
222+
locations_default(loc, f, _, _, _, _)
209223
}

java/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
| A.kt:4:21:4:29 | someFun(...) | file:///!unknown-binary-location/OC$C.class:0:0:0:0 | someFun | file:///!unknown-binary-location/OC$C.class:0:0:0:0 | C<D1,D2,E1,E2> | OC.class:0:0:0:0 | OC<F1,F2> |
21
| A.kt:4:21:4:29 | someFun(...) | file:///!unknown-binary-location/OC$C.class:0:0:0:0 | someFun | file:///!unknown-binary-location/OC$C.class:0:0:0:0 | C<D1,D2,E1,E2> | file:///!unknown-binary-location/OC.class:0:0:0:0 | OC<F1,F2> |

python/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}

ql/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}

ruby/ql/test/TestUtilities/InlineExpectationsTest.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ abstract private class Expectation extends FailureLocatable {
330330
override Location getLocation() { result = comment.getLocation() }
331331
}
332332

333+
private predicate onSameLine(ValidExpectation a, ActualResult b) {
334+
exists(string fname, int line, Location la, Location lb |
335+
// Join order intent:
336+
// Take the locations of ActualResults,
337+
// join with locations in the same file / on the same line,
338+
// then match those against ValidExpectations.
339+
la = a.getLocation() and
340+
pragma[only_bind_into](lb) = b.getLocation() and
341+
pragma[only_bind_into](la).hasLocationInfo(fname, line, _, _, _) and
342+
lb.hasLocationInfo(fname, line, _, _, _)
343+
)
344+
}
345+
333346
private class ValidExpectation extends Expectation, TValidExpectation {
334347
string tag;
335348
string value;
@@ -344,8 +357,7 @@ private class ValidExpectation extends Expectation, TValidExpectation {
344357
string getKnownFailure() { result = knownFailure }
345358

346359
predicate matchesActualResult(ActualResult actualResult) {
347-
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
348-
getLocation().getFile() = actualResult.getLocation().getFile() and
360+
onSameLine(pragma[only_bind_into](this), actualResult) and
349361
getTag() = actualResult.getTag() and
350362
getValue() = actualResult.getValue()
351363
}

0 commit comments

Comments
 (0)