From a34b3629a2df5c764c98bdd7b68343b63717d19e Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 19 Aug 2025 09:44:50 +0200 Subject: [PATCH 1/6] Java: accept new test results after extractor update --- .../test.expected | 120 ++++++------------ .../reflection/reflection.expected | 1 + .../test.expected | 117 ++++++----------- .../reflection/reflection.expected | 1 + 4 files changed, 77 insertions(+), 162 deletions(-) diff --git a/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected b/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected index b901340b9642..a56980d10ac4 100644 --- a/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected +++ b/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected @@ -16,30 +16,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection> | add | Entry | -| AbstractCollection> | addAll | Collection> | -| AbstractCollection> | contains | Object | -| AbstractCollection> | containsAll | Collection | -| AbstractCollection> | remove | Object | -| AbstractCollection> | removeAll | Collection | -| AbstractCollection> | retainAll | Collection | -| AbstractCollection> | toArray | T[] | -| AbstractCollection | add | K | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | -| AbstractCollection | add | Runnable | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractCollection | add | String | | AbstractCollection | addAll | Collection | | AbstractCollection | contains | Object | @@ -56,14 +32,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection | add | V | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractList | add | E | | AbstractList | add | int | | AbstractList | addAll | Collection | @@ -103,14 +71,14 @@ methodWithDuplicate | AbstractMap | put | V | | AbstractMap | putAll | Map | | AbstractMap | remove | Object | -| AbstractMap> | containsKey | Object | -| AbstractMap> | containsValue | Object | -| AbstractMap> | equals | Object | -| AbstractMap> | get | Object | -| AbstractMap> | put | Entry | -| AbstractMap> | put | Identity | -| AbstractMap> | putAll | Map> | -| AbstractMap> | remove | Object | +| AbstractMap | containsKey | Object | +| AbstractMap | containsValue | Object | +| AbstractMap | equals | Object | +| AbstractMap | get | Object | +| AbstractMap | put | Identity | +| AbstractMap | put | Object | +| AbstractMap | putAll | Map | +| AbstractMap | remove | Object | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | @@ -179,17 +147,6 @@ methodWithDuplicate | Collection | retainAll | Collection | | Collection | toArray | IntFunction | | Collection | toArray | T[] | -| Collection | add | Runnable | -| Collection | addAll | Collection | -| Collection | contains | Object | -| Collection | containsAll | Collection | -| Collection | equals | Object | -| Collection | remove | Object | -| Collection | removeAll | Collection | -| Collection | removeIf | Predicate | -| Collection | retainAll | Collection | -| Collection | toArray | IntFunction | -| Collection | toArray | T[] | | Collection | add | String | | Collection | addAll | Collection | | Collection | contains | Object | @@ -332,37 +289,36 @@ methodWithDuplicate | Map | replace | K | | Map | replace | V | | Map | replaceAll | BiFunction | -| Map> | compute | BiFunction,? extends Entry> | -| Map> | compute | Identity | -| Map> | computeIfAbsent | Function> | -| Map> | computeIfAbsent | Identity | -| Map> | computeIfPresent | BiFunction,? extends Entry> | -| Map> | computeIfPresent | Identity | -| Map> | containsKey | Object | -| Map> | containsValue | Object | -| Map> | copyOf | Map | -| Map> | entry | K | -| Map> | entry | V | -| Map> | equals | Object | -| Map> | forEach | BiConsumer> | -| Map> | get | Object | -| Map> | getOrDefault | Entry | -| Map> | getOrDefault | Object | -| Map> | merge | BiFunction,? super Entry,? extends Entry> | -| Map> | merge | Entry | -| Map> | merge | Identity | -| Map> | of | K | -| Map> | of | V | -| Map> | ofEntries | Entry[] | -| Map> | put | Entry | -| Map> | put | Identity | -| Map> | putAll | Map> | -| Map> | putIfAbsent | Entry | -| Map> | putIfAbsent | Identity | -| Map> | remove | Object | -| Map> | replace | Entry | -| Map> | replace | Identity | -| Map> | replaceAll | BiFunction,? extends Entry> | +| Map | compute | BiFunction | +| Map | compute | Identity | +| Map | computeIfAbsent | Function | +| Map | computeIfAbsent | Identity | +| Map | computeIfPresent | BiFunction | +| Map | computeIfPresent | Identity | +| Map | containsKey | Object | +| Map | containsValue | Object | +| Map | copyOf | Map | +| Map | entry | K | +| Map | entry | V | +| Map | equals | Object | +| Map | forEach | BiConsumer | +| Map | get | Object | +| Map | getOrDefault | Object | +| Map | merge | BiFunction | +| Map | merge | Identity | +| Map | merge | Object | +| Map | of | K | +| Map | of | V | +| Map | ofEntries | Entry[] | +| Map | put | Identity | +| Map | put | Object | +| Map | putAll | Map | +| Map | putIfAbsent | Identity | +| Map | putIfAbsent | Object | +| Map | remove | Object | +| Map | replace | Identity | +| Map | replace | Object | +| Map | replaceAll | BiFunction | | Map | compute | BiFunction | | Map | compute | K | | Map | computeIfAbsent | Function | diff --git a/java/ql/test-kotlin1/library-tests/reflection/reflection.expected b/java/ql/test-kotlin1/library-tests/reflection/reflection.expected index 7ce456cdcbb2..3bc2f9ce67d6 100644 --- a/java/ql/test-kotlin1/library-tests/reflection/reflection.expected +++ b/java/ql/test-kotlin1/library-tests/reflection/reflection.expected @@ -289,6 +289,7 @@ compGenerated | file:///LongProgression.class:0:0:0:0 | spliterator | Forwarder for a Kotlin class inheriting an interface default method | | file:///LongRange.class:0:0:0:0 | forEach | Forwarder for a Kotlin class inheriting an interface default method | | file:///LongRange.class:0:0:0:0 | spliterator | Forwarder for a Kotlin class inheriting an interface default method | +| file:///String.class:0:0:0:0 | getChars | Forwarder for a Kotlin class inheriting an interface default method | | file:///String.class:0:0:0:0 | isEmpty | Forwarder for a Kotlin class inheriting an interface default method | | reflection.kt:7:49:7:54 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | diff --git a/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected b/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected index 03e86e2d2a18..2495c1fc1572 100644 --- a/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected +++ b/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected @@ -16,30 +16,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection> | add | Entry | -| AbstractCollection> | addAll | Collection> | -| AbstractCollection> | contains | Object | -| AbstractCollection> | containsAll | Collection | -| AbstractCollection> | remove | Object | -| AbstractCollection> | removeAll | Collection | -| AbstractCollection> | retainAll | Collection | -| AbstractCollection> | toArray | T[] | -| AbstractCollection | add | K | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | -| AbstractCollection | add | Runnable | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractCollection | add | String | | AbstractCollection | addAll | Collection | | AbstractCollection | contains | Object | @@ -56,14 +32,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection | add | V | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractList | add | E | | AbstractList | add | int | | AbstractList | addAll | Collection | @@ -103,14 +71,14 @@ methodWithDuplicate | AbstractMap | put | V | | AbstractMap | putAll | Map | | AbstractMap | remove | Object | -| AbstractMap> | containsKey | Object | -| AbstractMap> | containsValue | Object | -| AbstractMap> | equals | Object | -| AbstractMap> | get | Object | -| AbstractMap> | put | Entry | -| AbstractMap> | put | Identity | -| AbstractMap> | putAll | Map> | -| AbstractMap> | remove | Object | +| AbstractMap | containsKey | Object | +| AbstractMap | containsValue | Object | +| AbstractMap | equals | Object | +| AbstractMap | get | Object | +| AbstractMap | put | Identity | +| AbstractMap | put | Object | +| AbstractMap | putAll | Map | +| AbstractMap | remove | Object | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | @@ -176,16 +144,6 @@ methodWithDuplicate | Collection | retainAll | Collection | | Collection | toArray | IntFunction | | Collection | toArray | T[] | -| Collection | add | Runnable | -| Collection | addAll | Collection | -| Collection | contains | Object | -| Collection | containsAll | Collection | -| Collection | remove | Object | -| Collection | removeAll | Collection | -| Collection | removeIf | Predicate | -| Collection | retainAll | Collection | -| Collection | toArray | IntFunction | -| Collection | toArray | T[] | | Collection | add | String | | Collection | addAll | Collection | | Collection | contains | Object | @@ -325,36 +283,35 @@ methodWithDuplicate | Map | replace | K | | Map | replace | V | | Map | replaceAll | BiFunction | -| Map> | compute | BiFunction,? extends Entry> | -| Map> | compute | Identity | -| Map> | computeIfAbsent | Function> | -| Map> | computeIfAbsent | Identity | -| Map> | computeIfPresent | BiFunction,? extends Entry> | -| Map> | computeIfPresent | Identity | -| Map> | containsKey | Object | -| Map> | containsValue | Object | -| Map> | copyOf | Map | -| Map> | entry | K | -| Map> | entry | V | -| Map> | forEach | BiConsumer> | -| Map> | get | Object | -| Map> | getOrDefault | Entry | -| Map> | getOrDefault | Object | -| Map> | merge | BiFunction,? super Entry,? extends Entry> | -| Map> | merge | Entry | -| Map> | merge | Identity | -| Map> | of | K | -| Map> | of | V | -| Map> | ofEntries | Entry[] | -| Map> | put | Entry | -| Map> | put | Identity | -| Map> | putAll | Map> | -| Map> | putIfAbsent | Entry | -| Map> | putIfAbsent | Identity | -| Map> | remove | Object | -| Map> | replace | Entry | -| Map> | replace | Identity | -| Map> | replaceAll | BiFunction,? extends Entry> | +| Map | compute | BiFunction | +| Map | compute | Identity | +| Map | computeIfAbsent | Function | +| Map | computeIfAbsent | Identity | +| Map | computeIfPresent | BiFunction | +| Map | computeIfPresent | Identity | +| Map | containsKey | Object | +| Map | containsValue | Object | +| Map | copyOf | Map | +| Map | entry | K | +| Map | entry | V | +| Map | forEach | BiConsumer | +| Map | get | Object | +| Map | getOrDefault | Object | +| Map | merge | BiFunction | +| Map | merge | Identity | +| Map | merge | Object | +| Map | of | K | +| Map | of | V | +| Map | ofEntries | Entry[] | +| Map | put | Identity | +| Map | put | Object | +| Map | putAll | Map | +| Map | putIfAbsent | Identity | +| Map | putIfAbsent | Object | +| Map | remove | Object | +| Map | replace | Identity | +| Map | replace | Object | +| Map | replaceAll | BiFunction | | Map | compute | BiFunction | | Map | compute | K | | Map | computeIfAbsent | Function | diff --git a/java/ql/test-kotlin2/library-tests/reflection/reflection.expected b/java/ql/test-kotlin2/library-tests/reflection/reflection.expected index 4074866da65f..b5de2b1adea3 100644 --- a/java/ql/test-kotlin2/library-tests/reflection/reflection.expected +++ b/java/ql/test-kotlin2/library-tests/reflection/reflection.expected @@ -329,6 +329,7 @@ compGenerated | file:///SignStyle.class:0:0:0:0 | getEntries | Default property accessor | | file:///StackWalker$ExtendedOption.class:0:0:0:0 | getEntries | Default property accessor | | file:///StackWalker$Option.class:0:0:0:0 | getEntries | Default property accessor | +| file:///String.class:0:0:0:0 | getChars | Forwarder for a Kotlin class inheriting an interface default method | | file:///String.class:0:0:0:0 | isEmpty | Forwarder for a Kotlin class inheriting an interface default method | | file:///TextStyle.class:0:0:0:0 | getEntries | Default property accessor | | file:///Thread$State.class:0:0:0:0 | getEntries | Default property accessor | From 5290f865e6a859ad926d945bf7b4af802063fb8a Mon Sep 17 00:00:00 2001 From: idrissrio Date: Mon, 1 Sep 2025 17:40:00 +0200 Subject: [PATCH 2/6] Java: Add failing test for Scoped Values --- .../scoped-values/ScopedValueFlowTest.java | 39 +++++++++++++++++++ .../dataflow/scoped-values/options | 1 + .../dataflow/scoped-values/test.expected | 0 .../dataflow/scoped-values/test.ql | 24 ++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java create mode 100644 java/ql/test/library-tests/dataflow/scoped-values/options create mode 100644 java/ql/test/library-tests/dataflow/scoped-values/test.expected create mode 100644 java/ql/test/library-tests/dataflow/scoped-values/test.ql diff --git a/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java b/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java new file mode 100644 index 000000000000..d71233f7dc8d --- /dev/null +++ b/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java @@ -0,0 +1,39 @@ +public class ScopedValueFlowTest { + private static final ScopedValue USER_CONTEXT = ScopedValue.newInstance(); + private static final ScopedValue SESSION_ID = ScopedValue.newInstance(); + + public static void main(String[] args) { + String userInput = args[0]; // source + + // Test 1: Basic scoped value binding and retrieval + ScopedValue.where(USER_CONTEXT, userInput) + .run(() -> { + String value = USER_CONTEXT.get(); + sink(value); // should flag: tainted data reaches sink + }); + + // Test 2: Multiple scoped value bindings with chaining + ScopedValue.where(USER_CONTEXT, userInput) + .where(SESSION_ID, "safe-one") + .run(() -> { + String user = USER_CONTEXT.get(); + String session = SESSION_ID.get(); + sink(user); // should flag: tainted data reaches sink + sink(session); // should NOT flag + }); + + ScopedValue.where(USER_CONTEXT, userInput) + .run(() -> { + String outer = USER_CONTEXT.get(); + ScopedValue.where(USER_CONTEXT, "safe-two") + .run(() -> { + String inner = USER_CONTEXT.get(); + sink(inner); // False Positive: currently flags (model limitation + }); + sink(outer); // should flag: tainted data reaches sink + }); + } + + public static void sink(String s) { + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/scoped-values/options b/java/ql/test/library-tests/dataflow/scoped-values/options new file mode 100644 index 000000000000..c793109355a5 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/scoped-values/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -source 25 -target 25 --enable-preview \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/scoped-values/test.expected b/java/ql/test/library-tests/dataflow/scoped-values/test.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/ql/test/library-tests/dataflow/scoped-values/test.ql b/java/ql/test/library-tests/dataflow/scoped-values/test.ql new file mode 100644 index 000000000000..43534d2d3d8a --- /dev/null +++ b/java/ql/test/library-tests/dataflow/scoped-values/test.ql @@ -0,0 +1,24 @@ +import java +import semmle.code.java.dataflow.TaintTracking + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { + exists(ArrayAccess aa | + aa.getArray().(VarAccess).getVariable().hasName("args") and + n.asExpr() = aa + ) + } + + predicate isSink(DataFlow::Node n) { + exists(MethodCall ma | + ma.getMethod().hasName("sink") and + n.asExpr() = ma.getAnArgument() + ) + } +} + +module Flow = TaintTracking::Global; + +from DataFlow::Node src, DataFlow::Node sink +where Flow::flow(src, sink) +select src, sink From d25641b803f1532222e387b322c7ca9c5892c41a Mon Sep 17 00:00:00 2001 From: idrissrio Date: Mon, 1 Sep 2025 17:41:02 +0200 Subject: [PATCH 3/6] Java: Add MaDs for `java.lang.scoped` --- java/ql/lib/ext/java.lang.scoped.model.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 java/ql/lib/ext/java.lang.scoped.model.yml diff --git a/java/ql/lib/ext/java.lang.scoped.model.yml b/java/ql/lib/ext/java.lang.scoped.model.yml new file mode 100644 index 000000000000..0b2c3af5a225 --- /dev/null +++ b/java/ql/lib/ext/java.lang.scoped.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.lang", "ScopedValue", False, "where", "(ScopedValue,Object)", "", "Argument[1]", "Argument[0].SyntheticField[java.lang.ScopedValue.boundValue]", "value", "manual"] + - ["java.lang", "ScopedValue", True, "get", "()", "", "Argument[this].SyntheticField[java.lang.ScopedValue.boundValue]", "ReturnValue", "value", "manual"] + - ["java.lang", "ScopedValue", False, "where", "(ScopedValue,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "ScopedValue$Carrier", False, "where", "(ScopedValue,Object)", "", "Argument[1]", "Argument[0].SyntheticField[java.lang.ScopedValue.boundValue]", "value", "manual"] + - ["java.lang", "ScopedValue$Carrier", False, "where", "(ScopedValue,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.lang", "ScopedValue", "newInstance", "()", "summary", "manual"] + - ["java.lang", "ScopedValue", "isBound", "()", "summary", "manual"] + - ["java.lang", "ScopedValue$Carrier", "run", "(Runnable)", "summary", "manual"] + - ["java.lang", "ScopedValue$Carrier", "call", "(Callable)", "summary", "manual"] \ No newline at end of file From 9bc14e0f071e7a3ed4a67e1c6c405646eea7b049 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Mon, 1 Sep 2025 17:41:58 +0200 Subject: [PATCH 4/6] Java: accept new test results --- .../test/library-tests/dataflow/scoped-values/test.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/test/library-tests/dataflow/scoped-values/test.expected b/java/ql/test/library-tests/dataflow/scoped-values/test.expected index e69de29bb2d1..5878a9931417 100644 --- a/java/ql/test/library-tests/dataflow/scoped-values/test.expected +++ b/java/ql/test/library-tests/dataflow/scoped-values/test.expected @@ -0,0 +1,4 @@ +| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:12:22:12:26 | value | +| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:21:22:21:25 | user | +| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:31:30:31:34 | inner | +| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:33:22:33:26 | outer | From 2c076f6b7acfe2c319c7d55de3e40589fcc8fb09 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 2 Sep 2025 13:28:44 +0200 Subject: [PATCH 5/6] Java: Add new change note --- java/ql/lib/change-notes/2025-09-02-scoped-values.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2025-09-02-scoped-values.md diff --git a/java/ql/lib/change-notes/2025-09-02-scoped-values.md b/java/ql/lib/change-notes/2025-09-02-scoped-values.md new file mode 100644 index 000000000000..8758d1268f36 --- /dev/null +++ b/java/ql/lib/change-notes/2025-09-02-scoped-values.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint flow model for `java.lang.ScopedValue`. \ No newline at end of file From 3320fa07bc8021eabb8e892990645492840aba8d Mon Sep 17 00:00:00 2001 From: Idriss Riouak Date: Tue, 2 Sep 2025 13:39:52 +0200 Subject: [PATCH 6/6] Java: Fix missing right brace in test comment Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../dataflow/scoped-values/ScopedValueFlowTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java b/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java index d71233f7dc8d..d540e9f854f9 100644 --- a/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java +++ b/java/ql/test/library-tests/dataflow/scoped-values/ScopedValueFlowTest.java @@ -28,7 +28,7 @@ public static void main(String[] args) { ScopedValue.where(USER_CONTEXT, "safe-two") .run(() -> { String inner = USER_CONTEXT.get(); - sink(inner); // False Positive: currently flags (model limitation + sink(inner); // False Positive: currently flags (model limitation) }); sink(outer); // should flag: tainted data reaches sink });