Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5255e16

Browse files
committed
Java: Sync files and make framework specific code.
1 parent 15c05e2 commit 5255e16

4 files changed

Lines changed: 98 additions & 11 deletions

File tree

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

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
*
66
* The CSV specification has the following columns:
77
* - Sources:
8-
* `namespace; type; subtypes; name; signature; ext; output; kind`
8+
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
99
* - Sinks:
10-
* `namespace; type; subtypes; name; signature; ext; input; kind`
10+
* `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
1111
* - Summaries:
12-
* `namespace; type; subtypes; name; signature; ext; input; output; kind`
12+
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
13+
* - Negative Summaries:
14+
* `namespace; type; name; signature; provenance`
1315
*
1416
* The interpretation of a row is similar to API-graphs with a left-to-right
1517
* reading.
@@ -182,6 +184,16 @@ class SummaryModelCsv extends Unit {
182184
abstract predicate row(string row);
183185
}
184186

187+
/**
188+
* A unit class for adding negative summary model rows.
189+
*
190+
* Extend this class to add additional flow summary definitions.
191+
*/
192+
class NegativeSummaryModelCsv extends Unit {
193+
/** Holds if `row` specifies a negative summary definition. */
194+
abstract predicate row(string row);
195+
}
196+
185197
private class SourceModelCsvBase extends SourceModelCsv {
186198
override predicate row(string row) {
187199
row =
@@ -422,6 +434,8 @@ private predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
422434

423435
private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
424436

437+
private predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) }
438+
425439
/** Holds if a source model exists for the given parameters. */
426440
predicate sourceModel(
427441
string namespace, string type, boolean subtypes, string name, string signature, string ext,
@@ -489,6 +503,20 @@ predicate summaryModel(
489503
row.splitAt(";", 9) = provenance
490504
}
491505

506+
/** Holds is a summary model exists indicating there is no flow for the given parameters. */
507+
predicate negativeSummaryModel(
508+
string namespace, string type, string name, string signature, string provenance
509+
) {
510+
exists(string row |
511+
negativeSummaryModel(row) and
512+
row.splitAt(";", 0) = namespace and
513+
row.splitAt(";", 1) = type and
514+
row.splitAt(";", 2) = name and
515+
row.splitAt(";", 3) = signature and
516+
row.splitAt(";", 4) = provenance
517+
)
518+
}
519+
492520
private predicate relevantPackage(string package) {
493521
sourceModel(package, _, _, _, _, _, _, _, _) or
494522
sinkModel(package, _, _, _, _, _, _, _, _) or
@@ -557,6 +585,10 @@ module CsvValidation {
557585
or
558586
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
559587
pred = "summary"
588+
or
589+
negativeSummaryModel(namespace, type, name, signature, provenance) and
590+
ext = "" and
591+
pred = "nonesummary"
560592
|
561593
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
562594
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
@@ -660,9 +692,13 @@ pragma[nomagic]
660692
private predicate elementSpec(
661693
string namespace, string type, boolean subtypes, string name, string signature, string ext
662694
) {
663-
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
664-
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
695+
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _)
696+
or
697+
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _)
698+
or
665699
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
700+
or
701+
negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false
666702
}
667703

668704
private string paramsStringPart(Callable c, int i) {
@@ -711,7 +747,7 @@ private Element interpretElement0(
711747
)
712748
}
713749

714-
/** Gets the source/sink/summary element corresponding to the supplied parameters. */
750+
/** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */
715751
Element interpretElement(
716752
string namespace, string type, boolean subtypes, string name, string signature, string ext
717753
) {

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

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,16 @@ module Public {
240240
*/
241241
predicate isAutoGenerated() { none() }
242242
}
243+
244+
/** A callable with a flow summary stating there is no flow via the callable. */
245+
class NegativeSummarizedCallable extends SummarizedCallableBase {
246+
NegativeSummarizedCallable() { negativeSummaryElement(this, _) }
247+
248+
/**
249+
* Holds if the none summary is auto generated.
250+
*/
251+
predicate isAutoGenerated() { negativeSummaryElement(this, true) }
252+
}
243253
}
244254

245255
/**
@@ -1094,7 +1104,7 @@ module Private {
10941104

10951105
/** Provides a query predicate for outputting a set of relevant flow summaries. */
10961106
module TestOutput {
1097-
/** A flow summary to include in the `summary/3` query predicate. */
1107+
/** A flow summary to include in the `summary/1` query predicate. */
10981108
abstract class RelevantSummarizedCallable instanceof SummarizedCallable {
10991109
/** Gets the string representation of this callable used by `summary/1`. */
11001110
abstract string getCallableCsv();
@@ -1109,15 +1119,27 @@ module Private {
11091119
string toString() { result = super.toString() }
11101120
}
11111121

1122+
/** A flow summary to include in the `negativeSummary/1` query predicate. */
1123+
abstract class RelevantNegativeSummarizedCallable instanceof NegativeSummarizedCallable {
1124+
/** Gets the string representation of this callable used by `summary/1`. */
1125+
abstract string getCallableCsv();
1126+
1127+
string toString() { result = super.toString() }
1128+
}
1129+
11121130
/** Render the kind in the format used in flow summaries. */
11131131
private string renderKind(boolean preservesValue) {
11141132
preservesValue = true and result = "value"
11151133
or
11161134
preservesValue = false and result = "taint"
11171135
}
11181136

1119-
private string renderProvenance(RelevantSummarizedCallable c) {
1120-
if c.(SummarizedCallable).isAutoGenerated() then result = "generated" else result = "manual"
1137+
private string renderProvenance(SummarizedCallable c) {
1138+
if c.isAutoGenerated() then result = "generated" else result = "manual"
1139+
}
1140+
1141+
private string renderProvenanceNegative(NegativeSummarizedCallable c) {
1142+
if c.isAutoGenerated() then result = "generated" else result = "manual"
11211143
}
11221144

11231145
/**
@@ -1132,8 +1154,23 @@ module Private {
11321154
|
11331155
c.relevantSummary(input, output, preservesValue) and
11341156
csv =
1135-
c.getCallableCsv() + getComponentStackCsv(input) + ";" + getComponentStackCsv(output) +
1136-
";" + renderKind(preservesValue) + ";" + renderProvenance(c)
1157+
c.getCallableCsv() // Callable information
1158+
+ getComponentStackCsv(input) + ";" // input
1159+
+ getComponentStackCsv(output) + ";" // output
1160+
+ renderKind(preservesValue) + ";" // kind
1161+
+ renderProvenance(c) // provenance
1162+
)
1163+
}
1164+
1165+
/**
1166+
* Holds if a negative flow summary `csv` exists (semi-colon separated format). Used for testing purposes.
1167+
* The syntax is: "namespace;type;name;signature;provenance"",
1168+
*/
1169+
query predicate negativeSummary(string csv) {
1170+
exists(RelevantNegativeSummarizedCallable c |
1171+
csv =
1172+
c.getCallableCsv() // Callable information
1173+
+ renderProvenanceNegative(c) // provenance
11371174
)
11381175
}
11391176
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ predicate summaryElement(Callable c, string input, string output, string kind, b
7878
)
7979
}
8080

81+
/**
82+
* Holds is an external flow summary exists for `c` which means that there is no
83+
* flow through `c` and a flag `generated` stating whether the summary is autogenerated.
84+
*/
85+
predicate negativeSummaryElement(Callable c, boolean generated) {
86+
exists(string namespace, string type, string name, string signature, string provenance |
87+
negativeSummaryModel(namespace, type, name, signature, provenance) and
88+
generated = isGenerated(provenance) and
89+
c = interpretElement(namespace, type, false, name, signature, "")
90+
)
91+
}
92+
8193
/** Gets the summary component for specification component `c`, if any. */
8294
bindingset[c]
8395
SummaryComponent interpretComponentSpecific(AccessPathToken c) {

java/ql/src/Telemetry/UnsupportedExternalAPIs.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
*/
88

99
import java
10+
import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
1011
import ExternalApi
1112

1213
private predicate getRelevantUsages(ExternalApi api, int usages) {
1314
not api.isUninteresting() and
1415
not api.isSupported() and
16+
not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable and
1517
usages =
1618
strictcount(Call c |
1719
c.getCallee().getSourceDeclaration() = api and

0 commit comments

Comments
 (0)