Skip to content

Commit 630ece6

Browse files
committed
C#/Java/Go: Neutrals are split into seperate classes.
1 parent bf69c76 commit 630ece6

File tree

11 files changed

+143
-145
lines changed

11 files changed

+143
-145
lines changed

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -934,21 +934,3 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
934934
interpretSummary(this, _, _, _, provenance)
935935
}
936936
}
937-
938-
// adapter class for converting Mad neutrals to `NeutralCallable`s
939-
private class NeutralCallableAdapter extends NeutralCallable {
940-
string kind;
941-
string provenance_;
942-
943-
NeutralCallableAdapter() {
944-
// Neutral models have not been implemented for CPP.
945-
none() and
946-
exists(this) and
947-
exists(kind) and
948-
exists(provenance_)
949-
}
950-
951-
override string getKind() { result = kind }
952-
953-
override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
954-
}

csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ private predicate interpretSummary(
556556
)
557557
}
558558

559-
private predicate interpretNeutral(UnboundCallable c, string kind, string provenance) {
559+
predicate interpretNeutral(UnboundCallable c, string kind, string provenance) {
560560
exists(string namespace, string type, string name, string signature |
561561
neutralModel(namespace, type, name, signature, kind, provenance) and
562562
c = interpretElement(namespace, type, false, name, signature, "")
@@ -613,18 +613,6 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
613613
}
614614
}
615615

616-
// adapter class for converting Mad neutrals to `NeutralCallable`s
617-
private class NeutralCallableAdapter extends NeutralCallable {
618-
string kind;
619-
string provenance_;
620-
621-
NeutralCallableAdapter() { interpretNeutral(this, kind, provenance_) }
622-
623-
override string getKind() { result = kind }
624-
625-
override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
626-
}
627-
628616
/**
629617
* A callable where there exists a MaD sink model that applies to it.
630618
*/

csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ private import semmle.code.csharp.dataflow.internal.ExternalFlow
1616
module Input implements InputSig<Location, DataFlowImplSpecific::CsharpDataFlow> {
1717
class SummarizedCallableBase = UnboundCallable;
1818

19+
predicate neutralElement(SummarizedCallableBase c, string kind, string provenance, boolean isExact) {
20+
interpretNeutral(c, kind, provenance) and
21+
// isExact has not been implemented yet.
22+
isExact = false
23+
}
24+
1925
ArgumentPosition callbackSelfParameterPosition() { result.isDelegateSelf() }
2026

2127
ReturnKind getStandardReturnValueKind() { result instanceof NormalReturnKind }
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import shared.FlowSummaries
22
import semmle.code.csharp.dataflow.internal.ExternalFlow
33

4-
final private class NeutralCallableFinal = NeutralCallable;
5-
6-
class RelevantNeutralCallable extends NeutralCallableFinal {
7-
final string getCallableCsv() { result = getSignature(this) }
4+
module R implements RelevantNeutralCallableSig<NeutralSummaryCallable> {
5+
class RelevantNeutralCallable extends NeutralSummaryCallable {
6+
final string getCallableCsv() { result = getSignature(this) }
7+
}
88
}
99

1010
class RelevantSourceCallable extends SourceCallable {
@@ -16,5 +16,5 @@ class RelevantSinkCallable extends SinkCallable {
1616
}
1717

1818
import TestSummaryOutput<IncludeSummarizedCallable>
19-
import TestNeutralOutput<RelevantNeutralCallable>
19+
import TestNeutralOutput<NeutralSummaryCallable, R>
2020
import External::TestSourceSinkOutput<RelevantSourceCallable, RelevantSinkCallable>

go/ql/lib/semmle/go/dataflow/ExternalFlow.qll

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -595,15 +595,3 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
595595
summaryElement(this, _, _, _, provenance, _)
596596
}
597597
}
598-
599-
// adapter class for converting Mad neutrals to `NeutralCallable`s
600-
private class NeutralCallableAdapter extends NeutralCallable {
601-
string kind;
602-
string provenance_;
603-
604-
NeutralCallableAdapter() { neutralElement(this, kind, provenance_) }
605-
606-
override string getKind() { result = kind }
607-
608-
override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
609-
}

go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ private string positionToString(int pos) {
2323
module Input implements InputSig<Location, DataFlowImplSpecific::GoDataFlow> {
2424
class SummarizedCallableBase = Callable;
2525

26+
predicate neutralElement(
27+
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
28+
) {
29+
exists(string namespace, string type, string name, string signature |
30+
neutralModel(namespace, type, name, signature, kind, provenance) and
31+
c.asFunction() = interpretElement(namespace, type, false, name, signature, "").asEntity()
32+
) and
33+
// isExact has not been implemented yet.
34+
isExact = false
35+
}
36+
2637
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
2738

2839
ReturnKind getStandardReturnValueKind() { result = getReturnKind(0) }
@@ -304,10 +315,7 @@ module Private {
304315
* and with provenance `provenance`.
305316
*/
306317
predicate neutralElement(Input::SummarizedCallableBase c, string kind, string provenance) {
307-
exists(string namespace, string type, string name, string signature |
308-
neutralModel(namespace, type, name, signature, kind, provenance) and
309-
c.asFunction() = interpretElement(namespace, type, false, name, signature, "").asEntity()
310-
)
318+
Input::neutralElement(c, kind, provenance, false)
311319
}
312320
}
313321

java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -627,21 +627,6 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
627627
override predicate hasExactModel() { summaryElement(this, _, _, _, _, _, true) }
628628
}
629629

630-
// adapter class for converting Mad neutrals to `NeutralCallable`s
631-
private class NeutralCallableAdapter extends NeutralCallable {
632-
string kind;
633-
string provenance_;
634-
boolean exact;
635-
636-
NeutralCallableAdapter() { neutralElement(this, kind, provenance_, exact) }
637-
638-
override string getKind() { result = kind }
639-
640-
override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
641-
642-
override predicate hasExactModel() { exact = true }
643-
}
644-
645630
/**
646631
* A callable where there exists a MaD sink model that applies to it.
647632
*/

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
private import java
22
private import DataFlowPrivate
33
private import DataFlowUtil
4+
private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow
45
private import semmle.code.java.dataflow.InstanceAccess
56
private import semmle.code.java.dataflow.internal.FlowSummaryImpl as Impl
67
private import semmle.code.java.dispatch.VirtualDispatch as VirtualDispatch

java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ private string positionToString(int pos) {
2929
module Input implements InputSig<Location, DataFlowImplSpecific::JavaDataFlow> {
3030
class SummarizedCallableBase = FlowSummary::SummarizedCallableBase;
3131

32+
predicate neutralElement(
33+
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
34+
) {
35+
exists(string namespace, string type, string name, string signature |
36+
neutralModel(namespace, type, name, signature, kind, provenance) and
37+
c.asCallable() = interpretElement(namespace, type, false, name, signature, "", isExact)
38+
)
39+
}
40+
3241
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
3342

3443
ReturnKind getStandardReturnValueKind() { any() }
@@ -332,18 +341,7 @@ module Private {
332341
)
333342
}
334343

335-
/**
336-
* Holds if a neutral model exists for `c` of kind `kind`
337-
* and with provenance `provenance`.
338-
*/
339-
predicate neutralElement(
340-
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
341-
) {
342-
exists(string namespace, string type, string name, string signature |
343-
neutralModel(namespace, type, name, signature, kind, provenance) and
344-
c.asCallable() = interpretElement(namespace, type, false, name, signature, "", isExact)
345-
)
346-
}
344+
predicate neutralElement = Input::neutralElement/4;
347345
}
348346

349347
/** Provides predicates for constructing summary components. */

shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 108 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> Lang> {
1919
string toString();
2020
}
2121

22+
/**
23+
* Holds if a neutral (MaD) model exists for `c` of kind `kind`
24+
* with provenance `provenance` and `isExact` is true if the model
25+
* signature matches `c` exactly - otherwise false.
26+
*/
27+
default predicate neutralElement(
28+
SummarizedCallableBase c, string kind, string provenance, boolean isExact
29+
) {
30+
none()
31+
}
32+
2233
/** Gets the parameter position representing a callback itself, if any. */
2334
default Lang::ArgumentPosition callbackSelfParameterPosition() { none() }
2435

@@ -261,64 +272,106 @@ module Make<
261272
predicate hasExactModel() { none() }
262273
}
263274

264-
final private class NeutralCallableFinal = NeutralCallable;
275+
private signature predicate hasKindSig(string kind);
265276

266-
/**
267-
* A callable where there is no flow via the callable.
268-
*/
269-
class NeutralSummaryCallable extends NeutralCallableFinal {
270-
NeutralSummaryCallable() { this.getKind() = "summary" }
271-
}
277+
signature class NeutralCallableSig extends SummarizedCallableBaseFinal {
278+
/**
279+
* Holds if the neutral has provenance `p`.
280+
*/
281+
predicate hasProvenance(Provenance p);
272282

273-
/**
274-
* A callable that has a neutral source model.
275-
*/
276-
class NeutralSourceCallable extends NeutralCallableFinal {
277-
NeutralSourceCallable() { this.getKind() = "source" }
283+
/**
284+
* Gets the kind of the neutral.
285+
*/
286+
string getKind();
287+
288+
/**
289+
* Holds if the neutral is auto generated.
290+
*/
291+
predicate hasGeneratedModel();
292+
293+
/**
294+
* Holds if there exists a manual neutral that applies to this callable.
295+
*/
296+
predicate hasManualModel();
278297
}
279298

280299
/**
281-
* A callable that has a neutral sink model.
300+
* A module for constructing classes of neutral callables.
282301
*/
283-
class NeutralSinkCallable extends NeutralCallableFinal {
284-
NeutralSinkCallable() { this.getKind() = "sink" }
302+
private module MakeNeutralCallable<hasKindSig/1 hasKind> {
303+
class NeutralCallable extends SummarizedCallableBaseFinal {
304+
private string kind;
305+
private string provenance_;
306+
private boolean exact;
307+
308+
NeutralCallable() {
309+
hasKind(kind) and
310+
neutralElement(this, kind, provenance_, exact)
311+
}
312+
313+
/**
314+
* Gets the kind of the neutral.
315+
*/
316+
string getKind() { result = kind }
317+
318+
/**
319+
* Holds if the neutral has provenance `p`.
320+
*/
321+
predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
322+
323+
/**
324+
* Holds if the neutral is auto generated.
325+
*/
326+
final predicate hasGeneratedModel() {
327+
any(Provenance p | this.hasProvenance(p)).isGenerated()
328+
}
329+
330+
/**
331+
* Holds if there exists a manual neutral that applies to this callable.
332+
*/
333+
final predicate hasManualModel() { any(Provenance p | this.hasProvenance(p)).isManual() }
334+
335+
/**
336+
* Holds if there exists a model for which this callable is an exact
337+
* match, that is, no overriding was used to identify this callable from
338+
* the model.
339+
*/
340+
predicate hasExactModel() { exact = true }
341+
}
285342
}
286343

344+
private predicate neutralSummaryKind(string kind) { kind = "summary" }
345+
287346
/**
288-
* A callable that has a neutral model.
347+
* A callable where there exists a MaD neutral summary model that applies to it.
289348
*/
290-
abstract class NeutralCallable extends SummarizedCallableBaseFinal {
291-
bindingset[this]
292-
NeutralCallable() { exists(this) }
349+
class NeutralSummaryCallable = MakeNeutralCallable<neutralSummaryKind/1>::NeutralCallable;
293350

294-
/**
295-
* Holds if the neutral is auto generated.
296-
*/
297-
final predicate hasGeneratedModel() {
298-
any(Provenance p | this.hasProvenance(p)).isGenerated()
299-
}
351+
private predicate neutralSourceKind(string kind) { kind = "source" }
300352

301-
/**
302-
* Holds if there exists a manual neutral that applies to this callable.
303-
*/
304-
final predicate hasManualModel() { any(Provenance p | this.hasProvenance(p)).isManual() }
353+
/**
354+
* A callable where there exists a MaD neutral source model that applies to it.
355+
*/
356+
class NeutralSourceCallable = MakeNeutralCallable<neutralSourceKind/1>::NeutralCallable;
305357

306-
/**
307-
* Holds if the neutral has provenance `p`.
308-
*/
309-
abstract predicate hasProvenance(Provenance p);
358+
private predicate neutralSinkKind(string kind) { kind = "sink" }
310359

311-
/**
312-
* Gets the kind of the neutral.
313-
*/
314-
abstract string getKind();
360+
/**
361+
* A callable where there exists a MaD neutral sink model that applies to it.
362+
*/
363+
class NeutralSinkCallable = MakeNeutralCallable<neutralSinkKind/1>::NeutralCallable;
315364

316-
/**
317-
* Holds if there exists a model for which this callable is an exact
318-
* match, that is, no overriding was used to identify this callable from
319-
* the model.
320-
*/
321-
predicate hasExactModel() { none() }
365+
/**
366+
* A callable where there exist a MaD neutral (summary, source or sink) model
367+
* that applies to it.
368+
*/
369+
class NeutralCallable extends SummarizedCallableBaseFinal {
370+
NeutralCallable() {
371+
this instanceof NeutralSummaryCallable or
372+
this instanceof NeutralSourceCallable or
373+
this instanceof NeutralSinkCallable
374+
}
322375
}
323376
}
324377

@@ -1880,13 +1933,20 @@ module Make<
18801933
}
18811934

18821935
/** A summarized callable relevant for testing. */
1883-
signature class RelevantNeutralCallableSig extends NeutralCallable {
1884-
/** Gets the string representation of this callable used by `neutral/1`. */
1885-
string getCallableCsv();
1936+
signature module RelevantNeutralCallableSig<NeutralCallableSig NeutralCallableInput> {
1937+
class RelevantNeutralCallable extends NeutralCallableInput {
1938+
/** Gets the string representation of this callable used by `neutral/1`. */
1939+
string getCallableCsv();
1940+
}
18861941
}
18871942

1888-
module TestNeutralOutput<RelevantNeutralCallableSig RelevantNeutralCallable> {
1889-
private string renderProvenance(NeutralCallable c) {
1943+
module TestNeutralOutput<
1944+
NeutralCallableSig NeutralCallableInput,
1945+
RelevantNeutralCallableSig<NeutralCallableInput> RelevantNeutralCallableInput>
1946+
{
1947+
class RelevantNeutralCallable = RelevantNeutralCallableInput::RelevantNeutralCallable;
1948+
1949+
private string renderProvenance(NeutralCallableInput c) {
18901950
exists(Provenance p | p.isManual() and c.hasProvenance(p) and result = p.toString())
18911951
or
18921952
not c.hasManualModel() and

0 commit comments

Comments
 (0)