Skip to content

Commit c060827

Browse files
authored
Merge pull request #14699 from smowton/smowton/feature/jdk21-sequenced-collections-models
Java: model JDK21 SequencedCollection, Set and Map
2 parents e16647f + 24b4b05 commit c060827

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The types `java.util.SequencedCollection`, `SequencedSet` and `SequencedMap`, as well as the related `Collections.unmodifiableSequenced*` methods are now modelled. This means alerts may be raised relating to data flow through these types and methods.

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ extensions:
9999
- ["java.util", "Collections", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"]
100100
- ["java.util", "Collections", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"]
101101
- ["java.util", "Collections", False, "unmodifiableNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
102+
- ["java.util", "Collections", False, "unmodifiableSequencedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
103+
- ["java.util", "Collections", False, "unmodifiableSequencedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"]
104+
- ["java.util", "Collections", False, "unmodifiableSequencedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"]
105+
- ["java.util", "Collections", False, "unmodifiableSequencedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
102106
- ["java.util", "Collections", False, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
103107
- ["java.util", "Collections", False, "unmodifiableSortedMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"]
104108
- ["java.util", "Collections", False, "unmodifiableSortedMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"]
@@ -320,6 +324,34 @@ extensions:
320324
- ["java.util", "Scanner", True, "useDelimiter", "", "", "Argument[this]", "ReturnValue", "value", "manual"]
321325
- ["java.util", "Scanner", True, "useLocale", "", "", "Argument[this]", "ReturnValue", "value", "manual"]
322326
- ["java.util", "Scanner", True, "useRadix", "", "", "Argument[this]", "ReturnValue", "value", "manual"]
327+
- ["java.util", "SequencedCollection", True, "addFirst", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
328+
- ["java.util", "SequencedCollection", True, "addLast", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
329+
- ["java.util", "SequencedCollection", True, "getFirst", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
330+
- ["java.util", "SequencedCollection", True, "getLast", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
331+
- ["java.util", "SequencedCollection", True, "removeFirst", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
332+
- ["java.util", "SequencedCollection", True, "removeLast", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
333+
- ["java.util", "SequencedCollection", True, "reversed", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
334+
- ["java.util", "SequencedMap", True, "firstEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
335+
- ["java.util", "SequencedMap", True, "firstEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
336+
- ["java.util", "SequencedMap", True, "lastEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
337+
- ["java.util", "SequencedMap", True, "lastEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
338+
- ["java.util", "SequencedMap", True, "pollFirstEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
339+
- ["java.util", "SequencedMap", True, "pollFirstEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
340+
- ["java.util", "SequencedMap", True, "pollLastEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
341+
- ["java.util", "SequencedMap", True, "pollLastEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
342+
- ["java.util", "SequencedMap", True, "putFirst", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"]
343+
- ["java.util", "SequencedMap", True, "putFirst", "", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"]
344+
- ["java.util", "SequencedMap", True, "putFirst", "", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"]
345+
- ["java.util", "SequencedMap", True, "putLast", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"]
346+
- ["java.util", "SequencedMap", True, "putLast", "", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"]
347+
- ["java.util", "SequencedMap", True, "putLast", "", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"]
348+
- ["java.util", "SequencedMap", True, "reversed", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
349+
- ["java.util", "SequencedMap", True, "reversed", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
350+
- ["java.util", "SequencedMap", True, "sequencedEntrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapKey", "value", "manual"]
351+
- ["java.util", "SequencedMap", True, "sequencedEntrySet", "", "", "Argument[this].MapValue", "ReturnValue.Element.MapValue", "value", "manual"]
352+
- ["java.util", "SequencedMap", True, "sequencedKeySet", "", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"]
353+
- ["java.util", "SequencedMap", True, "sequencedValues", "", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"]
354+
- ["java.util", "SequencedSet", True, "reversed", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
323355
- ["java.util", "Set", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
324356
- ["java.util", "Set", False, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
325357
- ["java.util", "Set", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"]

java/ql/test/library-tests/dataflow/collections/B.java

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,5 +1873,166 @@ void foo() throws InterruptedException {
18731873
Collection out = null;
18741874
Object[] in = storeArrayElement(source()); ((Collections)null).addAll(out,in); sink(readElement(out)); // $ hasValueFlow
18751875
}
1876+
// Java 21 sequenced collections tests:
1877+
{
1878+
// ["java.util", "SequencedCollection", True, "addFirst", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
1879+
SequencedCollection out = null;
1880+
Object in = source(); out.addFirst(in); sink(readElement(out)); // $ hasValueFlow
1881+
}
1882+
{
1883+
// ["java.util", "SequencedCollection", True, "addLast", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
1884+
SequencedCollection out = null;
1885+
Object in = source(); out.addLast(in); sink(readElement(out)); // $ hasValueFlow
1886+
}
1887+
{
1888+
// ["java.util", "SequencedCollection", True, "getFirst", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
1889+
Object out = null;
1890+
SequencedCollection in = storeElementList(source()); out = in.getFirst(); sink(out); // $ hasValueFlow
1891+
}
1892+
{
1893+
// ["java.util", "SequencedCollection", True, "getLast", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
1894+
Object out = null;
1895+
SequencedCollection in = storeElementList(source()); out = in.getLast(); sink(out); // $ hasValueFlow
1896+
}
1897+
{
1898+
// ["java.util", "SequencedCollection", True, "removeFirst", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
1899+
Object out = null;
1900+
SequencedCollection in = storeElementList(source()); out = in.removeFirst(); sink(out); // $ hasValueFlow
1901+
}
1902+
{
1903+
// ["java.util", "SequencedCollection", True, "removeLast", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
1904+
Object out = null;
1905+
SequencedCollection in = storeElementList(source()); out = in.removeLast(); sink(out); // $ hasValueFlow
1906+
}
1907+
{
1908+
// ["java.util", "SequencedCollection", True, "reversed", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
1909+
SequencedCollection out = null;
1910+
SequencedCollection in = storeElementList(source()); out = in.reversed(); sink(readElement(out)); // $ hasValueFlow
1911+
}
1912+
{
1913+
// ["java.util", "SequencedMap", True, "firstEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
1914+
Map.Entry out = null;
1915+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.firstEntry(); sink(readMapKey(out)); // $ hasValueFlow
1916+
}
1917+
{
1918+
// ["java.util", "SequencedMap", True, "lastEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
1919+
Map.Entry out = null;
1920+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.lastEntry(); sink(readMapKey(out)); // $ hasValueFlow
1921+
}
1922+
{
1923+
// - ["java.util", "SequencedMap", True, "pollFirstEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
1924+
Map.Entry out = null;
1925+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.pollFirstEntry(); sink(readMapKey(out)); // $ hasValueFlow
1926+
}
1927+
{
1928+
// ["java.util", "SequencedMap", True, "pollLastEntry", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
1929+
Map.Entry out = null;
1930+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.pollLastEntry(); sink(readMapKey(out)); // $ hasValueFlow
1931+
}
1932+
{
1933+
// ["java.util", "SequencedMap", True, "putFirst", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"]
1934+
Object out = null;
1935+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.putFirst(null, null); sink(out); // $ hasValueFlow
1936+
}
1937+
{
1938+
// ["java.util", "SequencedMap", True, "putFirst", "", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"]
1939+
SequencedMap out = null;
1940+
Object in = source(); out.putFirst(in, null); sink(readMapKey(out)); // $ hasValueFlow
1941+
}
1942+
{
1943+
// ["java.util", "SequencedMap", True, "putLast", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"]
1944+
Object out = null;
1945+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.putLast(null, null); sink(out); // $ hasValueFlow
1946+
}
1947+
{
1948+
// ["java.util", "SequencedMap", True, "putLast", "", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"]
1949+
SequencedMap out = null;
1950+
Object in = source(); out.putLast(in, null); sink(readMapKey(out)); // $ hasValueFlow
1951+
}
1952+
{
1953+
// ["java.util", "SequencedMap", True, "reversed", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"]
1954+
SequencedMap out = null;
1955+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.reversed(); sink(readMapKey(out)); // $ hasValueFlow
1956+
}
1957+
{
1958+
// ["java.util", "SequencedMap", True, "sequencedEntrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapKey", "value", "manual"]
1959+
Set<Map.Entry> out = null;
1960+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.sequencedEntrySet(); sink(readMapKey(readElement(out))); // $ hasValueFlow
1961+
}
1962+
{
1963+
// ["java.util", "SequencedMap", True, "firstEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
1964+
Map.Entry out = null;
1965+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.firstEntry(); sink(readMapValue(out)); // $ hasValueFlow
1966+
}
1967+
{
1968+
// ["java.util", "SequencedMap", True, "lastEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
1969+
Map.Entry out = null;
1970+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.lastEntry(); sink(readMapValue(out)); // $ hasValueFlow
1971+
}
1972+
{
1973+
// - ["java.util", "SequencedMap", True, "pollFirstEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
1974+
Map.Entry out = null;
1975+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.pollFirstEntry(); sink(readMapValue(out)); // $ hasValueFlow
1976+
}
1977+
{
1978+
// ["java.util", "SequencedMap", True, "pollLastEntry", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
1979+
Map.Entry out = null;
1980+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.pollLastEntry(); sink(readMapValue(out)); // $ hasValueFlow
1981+
}
1982+
{
1983+
// ["java.util", "SequencedMap", True, "putFirst", "", "", "Argument[0]", "Argument[this].MapValue", "value", "manual"]
1984+
SequencedMap out = null;
1985+
Object in = source(); out.putFirst(null, in); sink(readMapValue(out)); // $ hasValueFlow
1986+
}
1987+
{
1988+
// ["java.util", "SequencedMap", True, "putLast", "", "", "Argument[0]", "Argument[this].MapValue", "value", "manual"]
1989+
SequencedMap out = null;
1990+
Object in = source(); out.putLast(null, in); sink(readMapValue(out)); // $ hasValueFlow
1991+
}
1992+
{
1993+
// ["java.util", "SequencedMap", True, "reversed", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"]
1994+
SequencedMap out = null;
1995+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.reversed(); sink(readMapValue(out)); // $ hasValueFlow
1996+
}
1997+
{
1998+
// ["java.util", "SequencedMap", True, "sequencedEntrySet", "", "", "Argument[this].MapValue", "ReturnValue.Element.MapValue", "value", "manual"]
1999+
Set<Map.Entry> out = null;
2000+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.sequencedEntrySet(); sink(readMapValue(readElement(out))); // $ hasValueFlow
2001+
}
2002+
{
2003+
// ["java.util", "SequencedMap", True, "sequencedKeySet", "", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"]
2004+
Set out = null;
2005+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = in.sequencedKeySet(); sink(readElement(out)); // $ hasValueFlow
2006+
}
2007+
{
2008+
// ["java.util", "SequencedMap", True, "sequencedValues", "", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"]
2009+
SequencedCollection out = null;
2010+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = in.sequencedValues(); sink(readElement(out)); // $ hasValueFlow
2011+
}
2012+
{
2013+
// ["java.util", "SequencedSet", True, "reversed", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
2014+
SequencedSet out = null;
2015+
SequencedSet in = storeElementNavSet(source()); out = in.reversed(); sink(readElement(out)); // $ hasValueFlow
2016+
}
2017+
{
2018+
// ["java.util", "Collections", False, "unmodifiableSequencedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
2019+
SequencedCollection out = null;
2020+
SequencedCollection in = storeElementList(source()); out = Collections.unmodifiableSequencedCollection(in); sink(readElement(out)); // $ hasValueFlow
2021+
}
2022+
{
2023+
// ["java.util", "Collections", False, "unmodifiableSequencedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"]
2024+
SequencedMap out = null;
2025+
SequencedMap in = (SequencedMap)storeMapKey(source()); out = Collections.unmodifiableSequencedMap(in); sink(readMapKey(out)); // $ hasValueFlow
2026+
}
2027+
{
2028+
// ["java.util", "Collections", False, "unmodifiableSequencedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"]
2029+
SequencedMap out = null;
2030+
SequencedMap in = (SequencedMap)storeMapValue(source()); out = Collections.unmodifiableSequencedMap(in); sink(readMapValue(out)); // $ hasValueFlow
2031+
}
2032+
{
2033+
// ["java.util", "Collections", False, "unmodifiableSequencedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
2034+
SequencedSet out = null;
2035+
SequencedSet in = storeElementNavSet(source()); out = Collections.unmodifiableSequencedSet(in); sink(readElement(out)); // $ hasValueFlow
2036+
}
18762037
}
18772038
}

0 commit comments

Comments
 (0)