Skip to content

Commit a95aad5

Browse files
authored
Merge pull request github#13546 from michaelnebel/java/withoutelement
Java: Support for With[out]Element for MaD.
2 parents d12743d + 0ed724e commit a95aad5

File tree

7 files changed

+411
-368
lines changed

7 files changed

+411
-368
lines changed

docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ The following components are supported:
397397
- **SyntheticGlobal[**\ `name`\ **]** selects the synthetic global with name `name`.
398398
- **ArrayElement** selects the elements of an array.
399399
- **Element** selects the elements of a collection-like container.
400+
- **WithoutElement** selects a collection-like container without its elements. This is for input only.
401+
- **WithElement** selects the elements of a collection-like container, but points to the container itself. This is for input only.
400402
- **MapKey** selects the element keys of a map.
401403
- **MapValue** selects the element values of a map.
402404

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Add support for `WithElement` and `WithoutElement` for MaD access paths.

java/ql/lib/ext/java.util.model.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ extensions:
140140
- ["java.util", "LinkedHashSet", False, "LinkedHashSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
141141
- ["java.util", "LinkedList", False, "LinkedList", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
142142
- ["java.util", "List", True, "add", "(int,Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
143-
- ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"]
143+
- ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].WithElement", "Argument[this]", "value", "manual"]
144+
- ["java.util", "List", True, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
144145
- ["java.util", "List", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
145146
- ["java.util", "List", True, "get", "(int)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
146147
- ["java.util", "List", True, "listIterator", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
@@ -313,6 +314,7 @@ extensions:
313314
- ["java.util", "Scanner", True, "useLocale", "", "", "Argument[this]", "ReturnValue", "value", "manual"]
314315
- ["java.util", "Scanner", True, "useRadix", "", "", "Argument[this]", "ReturnValue", "value", "manual"]
315316
- ["java.util", "Set", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
317+
- ["java.util", "Set", False, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
316318
- ["java.util", "Set", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"]
317319
- ["java.util", "Set", False, "of", "(Object,Object)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"]
318320
- ["java.util", "Set", False, "of", "(Object,Object,Object)", "", "Argument[0..2]", "ReturnValue.Element", "value", "manual"]
@@ -424,10 +426,8 @@ extensions:
424426
# When `WithoutElement` is implemented, these should be changed to summary models of the form `Argument[this].WithoutElement -> Argument[this]`.
425427
- ["java.util", "Collection", "removeIf", "(Predicate)", "summary", "manual"]
426428
- ["java.util", "Iterator", "remove", "()", "summary", "manual"]
427-
- ["java.util", "List", "clear", "()", "summary", "manual"]
428429
- ["java.util", "List", "remove", "(Object)", "summary", "manual"]
429430
- ["java.util", "Map", "clear", "()", "summary", "manual"]
430-
- ["java.util", "Set", "clear", "()", "summary", "manual"]
431431
- ["java.util", "Set", "remove", "(Object)", "summary", "manual"]
432432
- ["java.util", "Set", "removeAll", "(Collection)", "summary", "manual"]
433433

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,25 @@
3535
* or method, or a parameter.
3636
* 7. The `input` column specifies how data enters the element selected by the
3737
* first 6 columns, and the `output` column specifies how data leaves the
38-
* element selected by the first 6 columns. An `input` can be either "",
39-
* "Argument[n]", "Argument[n1..n2]", "ReturnValue":
38+
* element selected by the first 6 columns. An `input` can be a dot separated
39+
* path consisting of either "", "Argument[n]", "Argument[n1..n2]",
40+
* "ReturnValue", "Element", "WithoutElement", or "WithElement":
4041
* - "": Selects a write to the selected element in case this is a field.
4142
* - "Argument[n]": Selects an argument in a call to the selected element.
4243
* The arguments are zero-indexed, and `this` specifies the qualifier.
4344
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
4445
* the given range. The range is inclusive at both ends.
4546
* - "ReturnValue": Selects a value being returned by the selected element.
4647
* This requires that the selected element is a method with a body.
48+
* - "Element": Selects the collection elements of the selected element.
49+
* - "WithoutElement": Selects the selected element but without
50+
* its collection elements.
51+
* - "WithElement": Selects the collection elements of the selected element, but
52+
* points to the selected element.
4753
*
48-
* An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter",
49-
* "Parameter[n]", "Parameter[n1..n2]", or "ReturnValue":
54+
* An `output` can be can be a dot separated path consisting of either "",
55+
* "Argument[n]", "Argument[n1..n2]", "Parameter", "Parameter[n]",
56+
* "Parameter[n1..n2]", "ReturnValue", or "Element":
5057
* - "": Selects a read of a selected field, or a selected parameter.
5158
* - "Argument[n]": Selects the post-update value of an argument in a call to the
5259
* selected element. That is, the value of the argument after the call returns.
@@ -61,6 +68,7 @@
6168
* - "Parameter[n1..n2]": Similar to "Parameter[n]" but selects any parameter
6269
* in the given range. The range is inclusive at both ends.
6370
* - "ReturnValue": Selects the return value of a call to the selected element.
71+
* - "Element": Selects the collection elements of the selected element.
6472
* 8. The `kind` column is a tag that can be referenced from QL to determine to
6573
* which classes the interpreted elements should be added. For example, for
6674
* sources "remote" indicates a default remote flow source, and for summaries

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ predicate neutralSummaryElement(SummarizedCallableBase c, string provenance) {
170170
bindingset[c]
171171
SummaryComponent interpretComponentSpecific(AccessPathToken c) {
172172
exists(Content content | parseContent(c, content) and result = SummaryComponent::content(content))
173+
or
174+
c = "WithoutElement" and result = SummaryComponent::withoutContent(any(CollectionContent cc))
175+
or
176+
c = "WithElement" and result = SummaryComponent::withContent(any(CollectionContent cc))
173177
}
174178

175179
/** Gets the summary component for specification component `c`, if any. */
@@ -196,6 +200,10 @@ private string getContentSpecific(Content c) {
196200
/** Gets the textual representation of the content in the format used for MaD models. */
197201
string getMadRepresentationSpecific(SummaryComponent sc) {
198202
exists(Content c | sc = TContentSummaryComponent(c) and result = getContentSpecific(c))
203+
or
204+
sc = TWithoutContentSummaryComponent(_) and result = "WithoutElement"
205+
or
206+
sc = TWithContentSummaryComponent(_) and result = "WithElement"
199207
}
200208

201209
bindingset[pos]

0 commit comments

Comments
 (0)