From e93b44670fba860c4e7bceea19d72a4c693a4d71 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 31 May 2023 16:08:01 +0200 Subject: [PATCH 01/23] Ruby: printCfg: only show graph for selected CfgScope --- .../ql/lib/ide-contextual-queries/printCfg.ql | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/ide-contextual-queries/printCfg.ql b/ruby/ql/lib/ide-contextual-queries/printCfg.ql index 9c42fe91361..108d5a0bceb 100644 --- a/ruby/ql/lib/ide-contextual-queries/printCfg.ql +++ b/ruby/ql/lib/ide-contextual-queries/printCfg.ql @@ -9,14 +9,45 @@ private import codeql.ruby.controlflow.internal.ControlFlowGraphImplShared::TestOutput private import codeql.IDEContextual +private import codeql.Locations +private import codeql.ruby.controlflow.ControlFlowGraph /** * Gets the source file to generate a CFG from. */ external string selectedSourceFile(); +external string selectedSourceLine(); + +external string selectedSourceColumn(); + +bindingset[file, line, column] +private CfgScope smallestEnclosingScope(File file, int line, int column) { + result = + min(Location loc, CfgScope scope | + loc = scope.getLocation() and + ( + loc.getStartLine() < line + or + loc.getStartLine() = line and loc.getStartColumn() <= column + ) and + ( + loc.getEndLine() > line + or + loc.getEndLine() = line and loc.getEndColumn() >= column + ) and + loc.getFile() = file + | + scope + order by + loc.getStartLine() desc, loc.getStartColumn() desc, loc.getEndLine(), loc.getEndColumn() + ) +} + class MyRelevantNode extends RelevantNode { MyRelevantNode() { - this.getScope().getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile()) + this.getScope() = + smallestEnclosingScope(getFileBySourceArchiveName(selectedSourceFile()), + selectedSourceLine().toInt(), selectedSourceColumn().toInt()) } } From 21ec83a1978c462f07bcff958e29562f491f3e13 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 23 Jun 2023 11:44:56 +0200 Subject: [PATCH 02/23] Java: Add MaD support for With[out]Element. --- .../java/dataflow/internal/FlowSummaryImplSpecific.qll | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index d9782c2eecf..b99c96c8085 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -170,6 +170,10 @@ predicate neutralSummaryElement(SummarizedCallableBase c, string provenance) { bindingset[c] SummaryComponent interpretComponentSpecific(AccessPathToken c) { exists(Content content | parseContent(c, content) and result = SummaryComponent::content(content)) + or + c = "WithoutElement" and result = SummaryComponent::withoutContent(any(CollectionContent cc)) + or + c = "WithElement" and result = SummaryComponent::withContent(any(CollectionContent cc)) } /** Gets the summary component for specification component `c`, if any. */ @@ -196,6 +200,10 @@ private string getContentSpecific(Content c) { /** Gets the textual representation of the content in the format used for MaD models. */ string getMadRepresentationSpecific(SummaryComponent sc) { exists(Content c | sc = TContentSummaryComponent(c) and result = getContentSpecific(c)) + or + sc = TWithoutContentSummaryComponent(_) and result = "WithoutElement" + or + sc = TWithContentSummaryComponent(_) and result = "WithElement" } bindingset[pos] From 0604a85bb1425ff0060d2f7878db461aabcee3b6 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 23 Jun 2023 14:43:29 +0200 Subject: [PATCH 03/23] Java: Add WithoutElement model for List.clear and add appropriate test. --- java/ql/lib/ext/java.util.model.yml | 2 +- java/ql/test/library-tests/dataflow/collections/B.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 15ab5e0c0be..ee0fe51d678 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -159,6 +159,7 @@ extensions: - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - ["java.util", "List", True, "subList", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", True, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["java.util", "ListIterator", True, "add", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util", "ListIterator", True, "previous", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "ListIterator", True, "set", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] @@ -424,7 +425,6 @@ extensions: # When `WithoutElement` is implemented, these should be changed to summary models of the form `Argument[this].WithoutElement -> Argument[this]`. - ["java.util", "Collection", "removeIf", "(Predicate)", "summary", "manual"] - ["java.util", "Iterator", "remove", "()", "summary", "manual"] - - ["java.util", "List", "clear", "()", "summary", "manual"] - ["java.util", "List", "remove", "(Object)", "summary", "manual"] - ["java.util", "Map", "clear", "()", "summary", "manual"] - ["java.util", "Set", "clear", "()", "summary", "manual"] diff --git a/java/ql/test/library-tests/dataflow/collections/B.java b/java/ql/test/library-tests/dataflow/collections/B.java index 0bb2b74d749..db5399efdd8 100644 --- a/java/ql/test/library-tests/dataflow/collections/B.java +++ b/java/ql/test/library-tests/dataflow/collections/B.java @@ -302,6 +302,16 @@ public class B { List out = null; Collection in = storeElementList(source()); out.addAll(0,in); sink(readElement(out)); // $ hasValueFlow } + { + // "java.util;List;true;clear;;;Argument[this].WithoutElement;Argument[this];value;manual" + List out = null; + List in = storeElementList(source()); out = in; out.clear(); sink(readElement(out)); // No flow + } + { + // "java.util;List;true;clear;;;Argument[this].WithoutElement;Argument[this];value;manual" + List out = null; + List in = (List)source(); out = in; out.clear(); sink(out); // $ hasValueFlow + } { // "java.util;Vector;true;elementAt;(int);;Element of Argument[this];ReturnValue;value;manual", Object out = null; From e97a4a1aeafb915891d4c3921f7416fd99591fe1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 4 Jul 2023 10:53:07 +0200 Subject: [PATCH 04/23] Java: Update telemetry test expected output. --- .../TopJdkApisTest/TopJdkApisTest.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected index 4fee1c07e06..37600f1f707 100644 --- a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected +++ b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected @@ -13,7 +13,7 @@ | java.time | 0 | 0 | 0 | 17 | 17 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.time.chrono | 0 | 0 | 0 | 1 | 1 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.time.format | 0 | 0 | 0 | 2 | 2 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | -| java.util | 0 | 0 | 84 | 68 | 152 | 0.5526315789473685 | 0.0 | 0.5526315789473685 | 0.0 | NaN | 0.4473684210526316 | +| java.util | 0 | 0 | 85 | 67 | 152 | 0.5592105263157895 | 0.0 | 0.5592105263157895 | 0.0 | NaN | 0.4407894736842105 | | java.util.concurrent | 0 | 0 | 9 | 9 | 18 | 0.5 | 0.0 | 0.5 | 0.0 | NaN | 0.5 | | java.util.concurrent.atomic | 0 | 0 | 2 | 11 | 13 | 0.15384615384615385 | 0.0 | 0.15384615384615385 | 0.0 | NaN | 0.8461538461538461 | | java.util.concurrent.locks | 0 | 0 | 0 | 2 | 2 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | From 99ac98bffcaf3a949acd6841412384b9509aba74 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 4 Jul 2023 11:23:16 +0200 Subject: [PATCH 05/23] Java: Re-factor a model to use WithElement (this model is already tested in collections/B.java). --- java/ql/lib/ext/java.util.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index ee0fe51d678..88feefc7dd8 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -140,7 +140,7 @@ extensions: - ["java.util", "LinkedHashSet", False, "LinkedHashSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "LinkedList", False, "LinkedList", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "List", True, "add", "(int,Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - - ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] + - ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].WithElement", "Argument[this]", "value", "manual"] - ["java.util", "List", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["java.util", "List", True, "get", "(int)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "List", True, "listIterator", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] From fc66b6ef9cc896f00e660b435ab66e9cb2ee75a5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 4 Jul 2023 11:44:38 +0200 Subject: [PATCH 06/23] Java: Update test comments to reflect the MaD syntax. --- .../library-tests/dataflow/collections/B.java | 720 +++++++++--------- 1 file changed, 360 insertions(+), 360 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/collections/B.java b/java/ql/test/library-tests/dataflow/collections/B.java index db5399efdd8..ec43b30c0fd 100644 --- a/java/ql/test/library-tests/dataflow/collections/B.java +++ b/java/ql/test/library-tests/dataflow/collections/B.java @@ -49,96 +49,96 @@ public class B { void foo() throws InterruptedException { { - // "java.util;Map$Entry;true;getKey;;;MapKey of Argument[this];ReturnValue;value;manual", + // "java.util;Map$Entry;true;getKey;;;Argument[this].MapKey;ReturnValue;value;manual", Object out = null; Object in = storeMapKeyEntry(source()); out = ((Map.Entry)in).getKey(); sink(out); // $ hasValueFlow } { - // "java.util;Map$Entry;true;getValue;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map$Entry;true;getValue;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValueEntry(source()); out = ((Map.Entry)in).getValue(); sink(out); // $ hasValueFlow } { - // "java.util;Map$Entry;true;setValue;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map$Entry;true;setValue;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValueEntry(source()); out = ((Map.Entry)in).setValue(null); sink(out); // $ hasValueFlow } { - // "java.util;Map$Entry;true;setValue;;;Argument[0];MapValue of Argument[this];value;manual", + // "java.util;Map$Entry;true;setValue;;;Argument[0];Argument[this].MapValue;value;manual", Map.Entry out = null; Object in = source(); out.setValue(in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.lang;Iterable;true;iterator;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.lang;Iterable;true;iterator;();;Argument[this].Element;ReturnValue.Element;value;manual", Iterator out = null; Iterable in = storeElementList(source()); out = in.iterator(); sink(readElement(out)); // $ hasValueFlow } { - // "java.lang;Iterable;true;spliterator;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.lang;Iterable;true;spliterator;();;Argument[this].Element;ReturnValue.Element;value;manual", Spliterator out = null; Iterable in = storeElementList(source()); out = in.spliterator(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Iterator;true;next;;;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Iterator;true;next;;;Argument[this].Element;ReturnValue;value;manual", Object out = null; Iterator in = storeElementListIterator(source()); out = in.next(); sink(out); // $ hasValueFlow } { - // "java.util;ListIterator;true;previous;;;Element of Argument[this];ReturnValue;value;manual", + // "java.util;ListIterator;true;previous;;;Argument[this].Element;ReturnValue;value;manual", Object out = null; ListIterator in = storeElementListIterator(source()); out = in.previous(); sink(out); // $ hasValueFlow } { - // "java.util;ListIterator;true;add;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;ListIterator;true;add;(Object);;Argument[0];Argument[this].Element;value;manual", ListIterator out = null; Object in = source(); out.add(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;ListIterator;true;set;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;ListIterator;true;set;(Object);;Argument[0];Argument[this].Element;value;manual", ListIterator out = null; Object in = source(); out.set(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Enumeration;true;asIterator;;;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Enumeration;true;asIterator;;;Argument[this].Element;ReturnValue.Element;value;manual", Iterator out = null; Enumeration in = storeElementEnumeration(source()); out = in.asIterator(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Enumeration;true;nextElement;;;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Enumeration;true;nextElement;;;Argument[this].Element;ReturnValue;value;manual", Object out = null; Enumeration in = storeElementEnumeration(source()); out = in.nextElement(); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;computeIfAbsent;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;computeIfAbsent;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).computeIfAbsent(null,null); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];ReturnValue;value;manual", + // "java.util;Map;true;computeIfAbsent;;;Argument[1].ReturnValue;ReturnValue;value;manual", Object out = ((Map)null).computeIfAbsent(null,k -> source()); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];MapValue of Argument[this];value;manual", + // "java.util;Map;true;computeIfAbsent;;;Argument[1].ReturnValue;Argument[this].MapValue;value;manual", Map out = null; out.computeIfAbsent(null,k -> source()); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;true;entrySet;;;MapValue of Argument[this];MapValue of Element of ReturnValue;value;manual", + // "java.util;Map;true;entrySet;;;Argument[this].MapValue;ReturnValue.Element.MapValue;value;manual", Set out = null; Object in = storeMapValue(source()); out = ((Map)in).entrySet(); sink(readMapValue(readElement(out))); // $ hasValueFlow } { - // "java.util;Map;true;entrySet;;;MapKey of Argument[this];MapKey of Element of ReturnValue;value;manual", + // "java.util;Map;true;entrySet;;;Argument[this].MapKey;ReturnValue.Element.MapKey;value;manual", Set out = null; Object in = storeMapKey(source()); out = ((Map)in).entrySet(); sink(readMapKey(readElement(out))); // $ hasValueFlow } { - // "java.util;Map;true;get;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;get;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).get(null); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;getOrDefault;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;getOrDefault;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).getOrDefault(null,null); sink(out); // $ hasValueFlow } @@ -148,157 +148,157 @@ public class B { Object in = source(); out = ((Map)null).getOrDefault(null,in); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;put;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;put;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).put(null,null); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;put;;;Argument[0];MapKey of Argument[this];value;manual", + // "java.util;Map;true;put;;;Argument[0];Argument[this].MapKey;value;manual", Map out = null; Object in = source(); out.put(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;true;put;;;Argument[1];MapValue of Argument[this];value;manual", + // "java.util;Map;true;put;;;Argument[1];Argument[this].MapValue;value;manual", Map out = null; Object in = source(); out.put(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;true;putIfAbsent;;;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;putIfAbsent;;;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).putIfAbsent(null,null); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;putIfAbsent;;;Argument[0];MapKey of Argument[this];value;manual", + // "java.util;Map;true;putIfAbsent;;;Argument[0];Argument[this].MapKey;value;manual", Map out = null; Object in = source(); out.putIfAbsent(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;true;putIfAbsent;;;Argument[1];MapValue of Argument[this];value;manual", + // "java.util;Map;true;putIfAbsent;;;Argument[1];Argument[this].MapValue;value;manual", Map out = null; Object in = source(); out.putIfAbsent(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;true;remove;(Object);;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;remove;(Object);;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).remove(null); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;replace;(Object,Object);;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Map;true;replace;(Object,Object);;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Map)in).replace(null,null); sink(out); // $ hasValueFlow } { - // "java.util;Map;true;replace;(Object,Object);;Argument[0];MapKey of Argument[this];value;manual", + // "java.util;Map;true;replace;(Object,Object);;Argument[0];Argument[this].MapKey;value;manual", Map out = null; Object in = source(); out.replace(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;true;replace;(Object,Object);;Argument[1];MapValue of Argument[this];value;manual", + // "java.util;Map;true;replace;(Object,Object);;Argument[1];Argument[this].MapValue;value;manual", Map out = null; Object in = source(); out.replace(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;true;replace;(Object,Object,Object);;Argument[0];MapKey of Argument[this];value;manual", + // "java.util;Map;true;replace;(Object,Object,Object);;Argument[0];Argument[this].MapKey;value;manual", Map out = null; Object in = source(); out.replace(in,null,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;true;replace;(Object,Object,Object);;Argument[2];MapValue of Argument[this];value;manual", + // "java.util;Map;true;replace;(Object,Object,Object);;Argument[2];Argument[this].MapValue;value;manual", Map out = null; Object in = source(); out.replace(null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;true;keySet;();;MapKey of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Map;true;keySet;();;Argument[this].MapKey;ReturnValue.Element;value;manual", Set out = null; Object in = storeMapKey(source()); out = ((Map)in).keySet(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Map;true;values;();;MapValue of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Map;true;values;();;Argument[this].MapValue;ReturnValue.Element;value;manual", Iterable out = null; Object in = storeMapValue(source()); out = ((Map)in).values(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];MapValue of Argument[this];value;manual", + // "java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];Argument[this].MapValue;value;manual", Map out = null; Object in = source(); out.merge(null,in,null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;true;putAll;(Map);;MapKey of Argument[0];MapKey of Argument[this];value;manual", + // "java.util;Map;true;putAll;(Map);;Argument[0].MapKey;Argument[this].MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out.putAll((Map)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;true;putAll;(Map);;MapValue of Argument[0];MapValue of Argument[this];value;manual", + // "java.util;Map;true;putAll;(Map);;Argument[0].MapValue;Argument[this].MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out.putAll((Map)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collection;true;parallelStream;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Collection;true;parallelStream;();;Argument[this].Element;ReturnValue.Element;value;manual", Stream out = null; Collection in = storeElementList(source()); out = in.parallelStream(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collection;true;stream;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Collection;true;stream;();;Argument[this].Element;ReturnValue.Element;value;manual", Stream out = null; Collection in = storeElementList(source()); out = in.stream(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collection;true;toArray;;;Element of Argument[this];ArrayElement of ReturnValue;value;manual", + // "java.util;Collection;true;toArray;;;Argument[this].Element;ReturnValue.ArrayElement;value;manual", Object[] out = null; Collection in = storeElementList(source()); out = in.toArray(); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Collection;true;toArray;;;Element of Argument[this];ArrayElement of Argument[0];value;manual", + // "java.util;Collection;true;toArray;;;Argument[this].Element;Argument[0].ArrayElement;value;manual", Object[] out = null; Collection in = storeElementList(source()); in.toArray(out); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Collection;true;add;;;Argument[0];Element of Argument[this];value;manual", + // "java.util;Collection;true;add;;;Argument[0];Argument[this].Element;value;manual", Collection out = null; Object in = source(); out.add(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collection;true;addAll;;;Element of Argument[0];Element of Argument[this];value;manual", + // "java.util;Collection;true;addAll;;;Argument[0].Element;Argument[this].Element;value;manual", Collection out = null; Collection in = storeElementList(source()); out.addAll(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;true;get;(int);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;List;true;get;(int);;Argument[this].Element;ReturnValue;value;manual", Object out = null; List in = storeElementList(source()); out = in.get(0); sink(out); // $ hasValueFlow } { - // "java.util;List;true;listIterator;;;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;List;true;listIterator;;;Argument[this].Element;ReturnValue.Element;value;manual", ListIterator out = null; List in = storeElementList(source()); out = in.listIterator(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;true;remove;(int);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;List;true;remove;(int);;Argument[this].Element;ReturnValue;value;manual", Object out = null; List in = storeElementList(source()); out = in.remove(0); sink(out); // $ hasValueFlow } { - // "java.util;List;true;set;(int,Object);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;List;true;set;(int,Object);;Argument[this].Element;ReturnValue;value;manual", Object out = null; List in = storeElementList(source()); out = in.set(0,null); sink(out); // $ hasValueFlow } { - // "java.util;List;true;set;(int,Object);;Argument[1];Element of Argument[this];value;manual", + // "java.util;List;true;set;(int,Object);;Argument[1];Argument[this].Element;value;manual", List out = null; Object in = source(); out.set(0,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;true;subList;;;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;List;true;subList;;;Argument[this].Element;ReturnValue.Element;value;manual", List out = null; List in = storeElementList(source()); out = in.subList(0,0); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;true;add;(int,Object);;Argument[1];Element of Argument[this];value;manual", + // "java.util;List;true;add;(int,Object);;Argument[1];Argument[this].Element;value;manual", List out = null; Object in = source(); out.add(0,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;true;addAll;(int,Collection);;Element of Argument[1];Element of Argument[this];value;manual", + // "java.util;List;true;addAll;(int,Collection);;Argument[1].Element;Argument[this].Element;value;manual", List out = null; Collection in = storeElementList(source()); out.addAll(0,in); sink(readElement(out)); // $ hasValueFlow } @@ -313,1552 +313,1552 @@ public class B { List in = (List)source(); out = in; out.clear(); sink(out); // $ hasValueFlow } { - // "java.util;Vector;true;elementAt;(int);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Vector;true;elementAt;(int);;Argument[this].Element;ReturnValue;value;manual", Object out = null; Vector in = storeElementStack(source()); out = in.elementAt(0); sink(out); // $ hasValueFlow } { - // "java.util;Vector;true;elements;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Vector;true;elements;();;Argument[this].Element;ReturnValue.Element;value;manual", Enumeration out = null; Vector in = storeElementStack(source()); out = in.elements(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Vector;true;firstElement;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Vector;true;firstElement;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Vector in = storeElementStack(source()); out = in.firstElement(); sink(out); // $ hasValueFlow } { - // "java.util;Vector;true;lastElement;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Vector;true;lastElement;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Vector in = storeElementStack(source()); out = in.lastElement(); sink(out); // $ hasValueFlow } { - // "java.util;Vector;true;addElement;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Vector;true;addElement;(Object);;Argument[0];Argument[this].Element;value;manual", Vector out = null; Object in = source(); out.addElement(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Vector;true;insertElementAt;(Object,int);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Vector;true;insertElementAt;(Object,int);;Argument[0];Argument[this].Element;value;manual", Vector out = null; Object in = source(); out.insertElementAt(in,0); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Vector;true;setElementAt;(Object,int);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Vector;true;setElementAt;(Object,int);;Argument[0];Argument[this].Element;value;manual", Vector out = null; Object in = source(); out.setElementAt(in,0); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Vector;true;copyInto;(Object[]);;Element of Argument[this];ArrayElement of Argument[0];value;manual", + // "java.util;Vector;true;copyInto;(Object[]);;Argument[this].Element;Argument[0].ArrayElement;value;manual", Object[] out = null; Vector in = storeElementStack(source()); in.copyInto(out); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Stack;true;peek;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Stack;true;peek;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Stack in = storeElementStack(source()); out = in.peek(); sink(out); // $ hasValueFlow } { - // "java.util;Stack;true;pop;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Stack;true;pop;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Stack in = storeElementStack(source()); out = in.pop(); sink(out); // $ hasValueFlow } { - // "java.util;Stack;true;push;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Stack;true;push;(Object);;Argument[0];Argument[this].Element;value;manual", Stack out = null; Object in = source(); out.push(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Queue;true;element;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Queue;true;element;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Queue in = storeElementBlockingDeque(source()); out = in.element(); sink(out); // $ hasValueFlow } { - // "java.util;Queue;true;peek;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Queue;true;peek;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Queue in = storeElementBlockingDeque(source()); out = in.peek(); sink(out); // $ hasValueFlow } { - // "java.util;Queue;true;poll;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Queue;true;poll;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Queue in = storeElementBlockingDeque(source()); out = in.poll(); sink(out); // $ hasValueFlow } { - // "java.util;Queue;true;remove;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Queue;true;remove;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Queue in = storeElementBlockingDeque(source()); out = in.remove(); sink(out); // $ hasValueFlow } { - // "java.util;Queue;true;offer;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Queue;true;offer;(Object);;Argument[0];Argument[this].Element;value;manual", Queue out = null; Object in = source(); out.offer(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Deque;true;descendingIterator;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Deque;true;descendingIterator;();;Argument[this].Element;ReturnValue.Element;value;manual", Iterator out = null; Deque in = storeElementBlockingDeque(source()); out = in.descendingIterator(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Deque;true;getFirst;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;getFirst;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.getFirst(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;getLast;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;getLast;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.getLast(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;peekFirst;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;peekFirst;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.peekFirst(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;peekLast;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;peekLast;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.peekLast(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;pollFirst;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;pollFirst;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.pollFirst(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;pollLast;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;pollLast;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.pollLast(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;pop;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;pop;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.pop(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;removeFirst;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;removeFirst;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.removeFirst(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;removeLast;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;Deque;true;removeLast;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; Deque in = storeElementBlockingDeque(source()); out = in.removeLast(); sink(out); // $ hasValueFlow } { - // "java.util;Deque;true;push;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Deque;true;push;(Object);;Argument[0];Argument[this].Element;value;manual", Deque out = null; Object in = source(); out.push(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Deque;true;offerLast;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Deque;true;offerLast;(Object);;Argument[0];Argument[this].Element;value;manual", Deque out = null; Object in = source(); out.offerLast(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Deque;true;offerFirst;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Deque;true;offerFirst;(Object);;Argument[0];Argument[this].Element;value;manual", Deque out = null; Object in = source(); out.offerFirst(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Deque;true;addLast;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Deque;true;addLast;(Object);;Argument[0];Argument[this].Element;value;manual", Deque out = null; Object in = source(); out.addLast(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Deque;true;addFirst;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util;Deque;true;addFirst;(Object);;Argument[0];Argument[this].Element;value;manual", Deque out = null; Object in = source(); out.addFirst(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Element of Argument[this];ReturnValue;value;manual", + // "java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Argument[this].Element;ReturnValue;value;manual", Object out = null; BlockingDeque in = storeElementBlockingDeque(source()); out = in.pollFirst(0,null); sink(out); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Element of Argument[this];ReturnValue;value;manual", + // "java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Argument[this].Element;ReturnValue;value;manual", Object out = null; BlockingDeque in = storeElementBlockingDeque(source()); out = in.pollLast(0,null); sink(out); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;takeFirst;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util.concurrent;BlockingDeque;true;takeFirst;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; BlockingDeque in = storeElementBlockingDeque(source()); out = in.takeFirst(); sink(out); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;takeLast;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util.concurrent;BlockingDeque;true;takeLast;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; BlockingDeque in = storeElementBlockingDeque(source()); out = in.takeLast(); sink(out); // $ hasValueFlow } { - // "java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Element of Argument[this];ReturnValue;value;manual", + // "java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Argument[this].Element;ReturnValue;value;manual", Object out = null; BlockingQueue in = storeElementBlockingDeque(source()); out = in.poll(0,null); sink(out); // $ hasValueFlow } { - // "java.util.concurrent;BlockingQueue;true;take;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util.concurrent;BlockingQueue;true;take;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; BlockingQueue in = storeElementBlockingDeque(source()); out = in.take(); sink(out); // $ hasValueFlow } { - // "java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Argument[this].Element;value;manual", BlockingQueue out = null; Object in = source(); out.offer(in,0,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingQueue;true;put;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;BlockingQueue;true;put;(Object);;Argument[0];Argument[this].Element;value;manual", BlockingQueue out = null; Object in = source(); out.put(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;offerLast;(Object,long,TimeUnit);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;BlockingDeque;true;offerLast;(Object,long,TimeUnit);;Argument[0];Argument[this].Element;value;manual", BlockingDeque out = null; Object in = source(); out.offerLast(in,0,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;offerFirst;(Object,long,TimeUnit);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;BlockingDeque;true;offerFirst;(Object,long,TimeUnit);;Argument[0];Argument[this].Element;value;manual", BlockingDeque out = null; Object in = source(); out.offerFirst(in,0,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;putLast;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;BlockingDeque;true;putLast;(Object);;Argument[0];Argument[this].Element;value;manual", BlockingDeque out = null; Object in = source(); out.putLast(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingDeque;true;putFirst;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;BlockingDeque;true;putFirst;(Object);;Argument[0];Argument[this].Element;value;manual", BlockingDeque out = null; Object in = source(); out.putFirst(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Element of Argument[this];Element of Argument[0];value;manual", + // "java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Argument[this].Element;Argument[0].Element;value;manual", Collection out = null; BlockingQueue in = storeElementBlockingDeque(source()); in.drainTo(out,0); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Element of Argument[this];Element of Argument[0];value;manual", + // "java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Argument[this].Element;Argument[0].Element;value;manual", Collection out = null; BlockingQueue in = storeElementBlockingDeque(source()); in.drainTo(out); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;ConcurrentHashMap;true;elements;();;MapValue of Argument[this];Element of ReturnValue;value;manual", + // "java.util.concurrent;ConcurrentHashMap;true;elements;();;Argument[this].MapValue;ReturnValue.Element;value;manual", Enumeration out = null; Object in = storeMapValue(source()); out = ((ConcurrentHashMap)in).elements(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Dictionary;true;elements;();;MapValue of Argument[this];Element of ReturnValue;value;manual", + // "java.util;Dictionary;true;elements;();;Argument[this].MapValue;ReturnValue.Element;value;manual", Enumeration out = null; Object in = storeMapValue(source()); out = ((Dictionary)in).elements(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Dictionary;true;get;(Object);;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Dictionary;true;get;(Object);;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Dictionary)in).get(null); sink(out); // $ hasValueFlow } { - // "java.util;Dictionary;true;put;(Object,Object);;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Dictionary;true;put;(Object,Object);;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Dictionary)in).put(null,null); sink(out); // $ hasValueFlow } { - // "java.util;Dictionary;true;put;(Object,Object);;Argument[0];MapKey of Argument[this];value;manual", + // "java.util;Dictionary;true;put;(Object,Object);;Argument[0];Argument[this].MapKey;value;manual", Dictionary out = null; Object in = source(); out.put(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Dictionary;true;put;(Object,Object);;Argument[1];MapValue of Argument[this];value;manual", + // "java.util;Dictionary;true;put;(Object,Object);;Argument[1];Argument[this].MapValue;value;manual", Dictionary out = null; Object in = source(); out.put(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Dictionary;true;remove;(Object);;MapValue of Argument[this];ReturnValue;value;manual", + // "java.util;Dictionary;true;remove;(Object);;Argument[this].MapValue;ReturnValue;value;manual", Object out = null; Object in = storeMapValue(source()); out = ((Dictionary)in).remove(null); sink(out); // $ hasValueFlow } { - // "java.util;NavigableMap;true;ceilingEntry;(Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;ceilingEntry;(Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).ceilingEntry(null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;ceilingEntry;(Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;ceilingEntry;(Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).ceilingEntry(null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;descendingMap;();;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;descendingMap;();;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).descendingMap(); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;descendingMap;();;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;descendingMap;();;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).descendingMap(); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;firstEntry;();;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;firstEntry;();;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).firstEntry(); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;firstEntry;();;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;firstEntry;();;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).firstEntry(); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;floorEntry;(Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;floorEntry;(Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).floorEntry(null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;floorEntry;(Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;floorEntry;(Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).floorEntry(null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;headMap;(Object,boolean);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;headMap;(Object,boolean);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).headMap(null,true); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;headMap;(Object,boolean);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;headMap;(Object,boolean);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).headMap(null,true); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;higherEntry;(Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;higherEntry;(Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).higherEntry(null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;higherEntry;(Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;higherEntry;(Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).higherEntry(null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;lastEntry;();;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;lastEntry;();;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).lastEntry(); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;lastEntry;();;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;lastEntry;();;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).lastEntry(); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;lowerEntry;(Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;lowerEntry;(Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).lowerEntry(null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;lowerEntry;(Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;lowerEntry;(Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).lowerEntry(null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;pollFirstEntry;();;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;pollFirstEntry;();;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).pollFirstEntry(); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;pollFirstEntry;();;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;pollFirstEntry;();;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).pollFirstEntry(); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;pollLastEntry;();;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;pollLastEntry;();;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).pollLastEntry(); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;pollLastEntry;();;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;pollLastEntry;();;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).pollLastEntry(); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).subMap(null,true,null,true); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).subMap(null,true,null,true); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;tailMap;(Object,boolean);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;NavigableMap;true;tailMap;(Object,boolean);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((NavigableMap)in).tailMap(null,true); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;NavigableMap;true;tailMap;(Object,boolean);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;NavigableMap;true;tailMap;(Object,boolean);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((NavigableMap)in).tailMap(null,true); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;NavigableSet;true;ceiling;(Object);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;NavigableSet;true;ceiling;(Object);;Argument[this].Element;ReturnValue;value;manual", Object out = null; NavigableSet in = storeElementNavSet(source()); out = in.ceiling(null); sink(out); // $ hasValueFlow } { - // "java.util;NavigableSet;true;descendingIterator;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;NavigableSet;true;descendingIterator;();;Argument[this].Element;ReturnValue.Element;value;manual", Iterator out = null; NavigableSet in = storeElementNavSet(source()); out = in.descendingIterator(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;NavigableSet;true;descendingSet;();;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;NavigableSet;true;descendingSet;();;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = in.descendingSet(); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;NavigableSet;true;floor;(Object);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;NavigableSet;true;floor;(Object);;Argument[this].Element;ReturnValue;value;manual", Object out = null; NavigableSet in = storeElementNavSet(source()); out = in.floor(null); sink(out); // $ hasValueFlow } { - // "java.util;NavigableSet;true;headSet;(Object,boolean);;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;NavigableSet;true;headSet;(Object,boolean);;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = in.headSet(null,true); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;NavigableSet;true;higher;(Object);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;NavigableSet;true;higher;(Object);;Argument[this].Element;ReturnValue;value;manual", Object out = null; NavigableSet in = storeElementNavSet(source()); out = in.higher(null); sink(out); // $ hasValueFlow } { - // "java.util;NavigableSet;true;lower;(Object);;Element of Argument[this];ReturnValue;value;manual", + // "java.util;NavigableSet;true;lower;(Object);;Argument[this].Element;ReturnValue;value;manual", Object out = null; NavigableSet in = storeElementNavSet(source()); out = in.lower(null); sink(out); // $ hasValueFlow } { - // "java.util;NavigableSet;true;pollFirst;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;NavigableSet;true;pollFirst;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; NavigableSet in = storeElementNavSet(source()); out = in.pollFirst(); sink(out); // $ hasValueFlow } { - // "java.util;NavigableSet;true;pollLast;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;NavigableSet;true;pollLast;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; NavigableSet in = storeElementNavSet(source()); out = in.pollLast(); sink(out); // $ hasValueFlow } { - // "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = in.subSet(null,true,null,true); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;NavigableSet;true;tailSet;(Object,boolean);;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;NavigableSet;true;tailSet;(Object,boolean);;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = in.tailSet(null,true); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;SortedMap;true;headMap;(Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;SortedMap;true;headMap;(Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((SortedMap)in).headMap(null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;SortedMap;true;headMap;(Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;SortedMap;true;headMap;(Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((SortedMap)in).headMap(null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;SortedMap;true;subMap;(Object,Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;SortedMap;true;subMap;(Object,Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((SortedMap)in).subMap(null,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;SortedMap;true;subMap;(Object,Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;SortedMap;true;subMap;(Object,Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((SortedMap)in).subMap(null,null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;SortedMap;true;tailMap;(Object);;MapKey of Argument[this];MapKey of ReturnValue;value;manual", + // "java.util;SortedMap;true;tailMap;(Object);;Argument[this].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((SortedMap)in).tailMap(null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;SortedMap;true;tailMap;(Object);;MapValue of Argument[this];MapValue of ReturnValue;value;manual", + // "java.util;SortedMap;true;tailMap;(Object);;Argument[this].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((SortedMap)in).tailMap(null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;SortedSet;true;first;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;SortedSet;true;first;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; SortedSet in = storeElementNavSet(source()); out = in.first(); sink(out); // $ hasValueFlow } { - // "java.util;SortedSet;true;headSet;(Object);;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;SortedSet;true;headSet;(Object);;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; SortedSet in = storeElementNavSet(source()); out = in.headSet(null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;SortedSet;true;last;();;Element of Argument[this];ReturnValue;value;manual", + // "java.util;SortedSet;true;last;();;Argument[this].Element;ReturnValue;value;manual", Object out = null; SortedSet in = storeElementNavSet(source()); out = in.last(); sink(out); // $ hasValueFlow } { - // "java.util;SortedSet;true;subSet;(Object,Object);;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;SortedSet;true;subSet;(Object,Object);;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; SortedSet in = storeElementNavSet(source()); out = in.subSet(null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;SortedSet;true;tailSet;(Object);;Element of Argument[this];Element of ReturnValue;value;manual", + // "java.util;SortedSet;true;tailSet;(Object);;Argument[this].Element;ReturnValue.Element;value;manual", Set out = null; SortedSet in = storeElementNavSet(source()); out = in.tailSet(null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Argument[this].Element;value;manual", TransferQueue out = null; Object in = source(); out.tryTransfer(in,0,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;TransferQueue;true;transfer;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;TransferQueue;true;transfer;(Object);;Argument[0];Argument[this].Element;value;manual", TransferQueue out = null; Object in = source(); out.transfer(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util.concurrent;TransferQueue;true;tryTransfer;(Object);;Argument[0];Element of Argument[this];value;manual", + // "java.util.concurrent;TransferQueue;true;tryTransfer;(Object);;Argument[0];Argument[this].Element;value;manual", TransferQueue out = null; Object in = source(); out.tryTransfer(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;copyOf;(Collection);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", List out = null; Collection in = storeElementList(source()); out = List.copyOf(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", List out = null; Object[] in = storeArrayElement(source()); out = List.of(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(in,null,null,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,in,null,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,in,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[9];Element of ReturnValue;value;manual", + // "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[9];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = List.of(null,null,null,null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Map;false;copyOf;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = Map.copyOf((Map)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;copyOf;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = Map.copyOf((Map)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;entry;(Object,Object);;Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;entry;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", Map.Entry out = null; Object in = source(); out = Map.entry(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;entry;(Object,Object);;Argument[1];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;entry;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", Map.Entry out = null; Object in = source(); out = Map.entry(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[0];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[1];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[1];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[2];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[2];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[3];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[3];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[4];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[4];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[5];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[5];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[6];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[6];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[7];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[7];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[8];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[8];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[9];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[9];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[10];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[10];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[11];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[11];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[12];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[12];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[13];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[13];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[14];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[14];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[15];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[15];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[16];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[16];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[17];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[17];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[18];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[18];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;of;;;Argument[19];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;of;;;Argument[19];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = Map.of(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Map;false;ofEntries;;;MapKey of ArrayElement of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Map;false;ofEntries;;;Argument[0].MapKey.ArrayElement;ReturnValue.MapKey;value;manual", Map out = null; Object[] in = storeArrayElement(storeMapKey(source())); out = Map.ofEntries((Map.Entry[])in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Map;false;ofEntries;;;MapValue of ArrayElement of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Map;false;ofEntries;;;Argument[0].MapValue.ArrayElement;ReturnValue.MapValue;value;manual", Map out = null; Object[] in = storeArrayElement(storeMapValue(source())); out = Map.ofEntries((Map.Entry[])in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Set;false;copyOf;(Collection);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; Collection in = storeElementList(source()); out = Set.copyOf(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", Set out = null; Object[] in = storeArrayElement(source()); out = Set.of(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(in,null,null,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,in,null,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,in,null,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[3];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,in,null,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[4];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,in,null,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[5];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,in,null,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[6];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,in,null,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[7];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,null,in,null,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[8];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,null,null,in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[9];Element of ReturnValue;value;manual", + // "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[9];ReturnValue.Element;value;manual", Set out = null; Object in = source(); out = Set.of(null,null,null,null,null,null,null,null,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;stream;;;ArrayElement of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Arrays;false;stream;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", Stream out = null; Object[] in = storeArrayElement(source()); out = ((Arrays)null).stream(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;spliterator;;;ArrayElement of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Arrays;false;spliterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", Spliterator out = null; Object[] in = storeArrayElement(source()); out = ((Arrays)null).spliterator(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;copyOfRange;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value;manual", + // "java.util;Arrays;false;copyOfRange;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", Object[] out = null; Object[] in = storeArrayElement(source()); out = ((Arrays)null).copyOfRange(in,0,0); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;copyOf;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value;manual", + // "java.util;Arrays;false;copyOf;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", Object[] out = null; Object[] in = storeArrayElement(source()); out = ((Arrays)null).copyOf(in,0); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;list;(Enumeration);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;list;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", List out = null; Enumeration in = storeElementEnumeration(source()); out = ((Collections)null).list(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;enumeration;(Collection);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;enumeration;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", Enumeration out = null; Collection in = storeElementList(source()); out = ((Collections)null).enumeration(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;nCopies;(int,Object);;Argument[1];Element of ReturnValue;value;manual", + // "java.util;Collections;false;nCopies;(int,Object);;Argument[1];ReturnValue.Element;value;manual", Collection out = null; Object in = source(); out = ((Collections)null).nCopies(0,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;singletonMap;(Object,Object);;Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;singletonMap;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", Map out = null; Object in = source(); out = ((Collections)null).singletonMap(in,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;singletonMap;(Object,Object);;Argument[1];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;singletonMap;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", Map out = null; Object in = source(); out = ((Collections)null).singletonMap(null,in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;singletonList;(Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;singletonList;(Object);;Argument[0];ReturnValue.Element;value;manual", List out = null; Object in = source(); out = ((Collections)null).singletonList(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;singleton;(Object);;Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;singleton;(Object);;Argument[0];ReturnValue.Element;value;manual", Collection out = null; Object in = source(); out = ((Collections)null).singleton(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).checkedNavigableMap((NavigableMap)in,null,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).checkedNavigableMap((NavigableMap)in,null,null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).checkedSortedMap((SortedMap)in,null,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).checkedSortedMap((SortedMap)in,null,null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedMap;(Map,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;checkedMap;(Map,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).checkedMap((Map)in,null,null); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedMap;(Map,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;checkedMap;(Map,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).checkedMap((Map)in,null,null); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedList;(List,Class);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;checkedList;(List,Class);;Argument[0].Element;ReturnValue.Element;value;manual", List out = null; List in = storeElementList(source()); out = ((Collections)null).checkedList(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = ((Collections)null).checkedNavigableSet(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; SortedSet in = storeElementNavSet(source()); out = ((Collections)null).checkedSortedSet(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedSet;(Set,Class);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;checkedSet;(Set,Class);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; Set in = storeElementNavSet(source()); out = ((Collections)null).checkedSet(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;checkedCollection;(Collection,Class);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;checkedCollection;(Collection,Class);;Argument[0].Element;ReturnValue.Element;value;manual", Collection out = null; Collection in = storeElementList(source()); out = ((Collections)null).checkedCollection(in,null); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).synchronizedNavigableMap((NavigableMap)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).synchronizedNavigableMap((NavigableMap)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).synchronizedSortedMap((SortedMap)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).synchronizedSortedMap((SortedMap)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedMap;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).synchronizedMap((Map)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedMap;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).synchronizedMap((Map)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedList;(List);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedList;(List);;Argument[0].Element;ReturnValue.Element;value;manual", List out = null; List in = storeElementList(source()); out = ((Collections)null).synchronizedList(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = ((Collections)null).synchronizedNavigableSet(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; SortedSet in = storeElementNavSet(source()); out = ((Collections)null).synchronizedSortedSet(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedSet;(Set);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; Set in = storeElementNavSet(source()); out = ((Collections)null).synchronizedSet(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;synchronizedCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;synchronizedCollection;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", Collection out = null; Collection in = storeElementList(source()); out = ((Collections)null).synchronizedCollection(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).unmodifiableNavigableMap((NavigableMap)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).unmodifiableNavigableMap((NavigableMap)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).unmodifiableSortedMap((SortedMap)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).unmodifiableSortedMap((SortedMap)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableMap;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", Map out = null; Object in = storeMapKey(source()); out = ((Collections)null).unmodifiableMap((Map)in); sink(readMapKey(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableMap;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", Map out = null; Object in = storeMapValue(source()); out = ((Collections)null).unmodifiableMap((Map)in); sink(readMapValue(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableList;(List);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableList;(List);;Argument[0].Element;ReturnValue.Element;value;manual", List out = null; List in = storeElementList(source()); out = ((Collections)null).unmodifiableList(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; NavigableSet in = storeElementNavSet(source()); out = ((Collections)null).unmodifiableNavigableSet(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; SortedSet in = storeElementNavSet(source()); out = ((Collections)null).unmodifiableSortedSet(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableSet;(Set);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; Set in = storeElementNavSet(source()); out = ((Collections)null).unmodifiableSet(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;unmodifiableCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Collections;false;unmodifiableCollection;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", Collection out = null; Collection in = storeElementList(source()); out = ((Collections)null).unmodifiableCollection(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;max;;;Element of Argument[0];ReturnValue;value;manual", + // "java.util;Collections;false;max;;;Argument[0].Element;ReturnValue;value;manual", Object out = null; Collection in = storeElementList(source()); out = ((Collections)null).max(in); sink(out); // $ hasValueFlow } { - // "java.util;Collections;false;min;;;Element of Argument[0];ReturnValue;value;manual", + // "java.util;Collections;false;min;;;Argument[0].Element;ReturnValue;value;manual", Object out = null; Collection in = storeElementList(source()); out = ((Collections)null).min(in); sink(out); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];Argument[0].ArrayElement;value;manual", Object[] out = null; Object in = source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(Object[],Object);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(Object[],Object);;Argument[1];Argument[0].ArrayElement;value;manual", Object[] out = null; Object in = source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(float[],int,int,float);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(float[],int,int,float);;Argument[3];Argument[0].ArrayElement;value;manual", float[] out = null; float in = (Float)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(float[],float);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(float[],float);;Argument[1];Argument[0].ArrayElement;value;manual", float[] out = null; float in = (Float)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(double[],int,int,double);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(double[],int,int,double);;Argument[3];Argument[0].ArrayElement;value;manual", double[] out = null; double in = (Double)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(double[],double);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(double[],double);;Argument[1];Argument[0].ArrayElement;value;manual", double[] out = null; double in = (Double)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(boolean[],int,int,boolean);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(boolean[],int,int,boolean);;Argument[3];Argument[0].ArrayElement;value;manual", boolean[] out = null; boolean in = (Boolean)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(boolean[],boolean);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(boolean[],boolean);;Argument[1];Argument[0].ArrayElement;value;manual", boolean[] out = null; boolean in = (Boolean)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(byte[],int,int,byte);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(byte[],int,int,byte);;Argument[3];Argument[0].ArrayElement;value;manual", byte[] out = null; byte in = (Byte)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(byte[],byte);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(byte[],byte);;Argument[1];Argument[0].ArrayElement;value;manual", byte[] out = null; byte in = (Byte)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(char[],int,int,char);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(char[],int,int,char);;Argument[3];Argument[0].ArrayElement;value;manual", char[] out = null; char in = (Character)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(char[],char);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(char[],char);;Argument[1];Argument[0].ArrayElement;value;manual", char[] out = null; char in = (Character)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(short[],int,int,short);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(short[],int,int,short);;Argument[3];Argument[0].ArrayElement;value;manual", short[] out = null; short in = (Short)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(short[],short);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(short[],short);;Argument[1];Argument[0].ArrayElement;value;manual", short[] out = null; short in = (Short)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(int[],int,int,int);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(int[],int,int,int);;Argument[3];Argument[0].ArrayElement;value;manual", int[] out = null; int in = (Integer)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(int[],int);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(int[],int);;Argument[1];Argument[0].ArrayElement;value;manual", int[] out = null; int in = (Integer)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(long[],int,int,long);;Argument[3];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(long[],int,int,long);;Argument[3];Argument[0].ArrayElement;value;manual", long[] out = null; long in = (Long)source(); ((Arrays)null).fill(out,0,0,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;fill;(long[],long);;Argument[1];ArrayElement of Argument[0];value;manual", + // "java.util;Arrays;false;fill;(long[],long);;Argument[1];Argument[0].ArrayElement;value;manual", long[] out = null; long in = (Long)source(); ((Arrays)null).fill(out,in); sink(readArrayElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;replaceAll;(List,Object,Object);;Argument[2];Element of Argument[0];value;manual", + // "java.util;Collections;false;replaceAll;(List,Object,Object);;Argument[2];Argument[0].Element;value;manual", List out = null; Object in = source(); ((Collections)null).replaceAll(out,null,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;copy;(List,List);;Element of Argument[1];Element of Argument[0];value;manual", + // "java.util;Collections;false;copy;(List,List);;Argument[1].Element;Argument[0].Element;value;manual", List out = null; List in = storeElementList(source()); ((Collections)null).copy(out,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;fill;(List,Object);;Argument[1];Element of Argument[0];value;manual", + // "java.util;Collections;false;fill;(List,Object);;Argument[1];Argument[0].Element;value;manual", List out = null; Object in = source(); ((Collections)null).fill(out,in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Arrays;false;asList;;;ArrayElement of Argument[0];Element of ReturnValue;value;manual", + // "java.util;Arrays;false;asList;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", List out = null; Object[] in = storeArrayElement(source()); out = ((Arrays)null).asList(in); sink(readElement(out)); // $ hasValueFlow } { - // "java.util;Collections;false;addAll;(Collection,Object[]);;ArrayElement of Argument[1];Element of Argument[0];value;manual" + // "java.util;Collections;false;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;value;manual" Collection out = null; Object[] in = storeArrayElement(source()); ((Collections)null).addAll(out,in); sink(readElement(out)); // $ hasValueFlow } From a8ccc8d980a3b7afa6a5f2182aa593fbaefc75b5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 4 Jul 2023 13:27:24 +0200 Subject: [PATCH 07/23] Java: Update MaD internal documentation. --- .../semmle/code/java/dataflow/ExternalFlow.qll | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index c04126d5f7f..5100cfe4482 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -35,8 +35,9 @@ * or method, or a parameter. * 7. The `input` column specifies how data enters the element selected by the * first 6 columns, and the `output` column specifies how data leaves the - * element selected by the first 6 columns. An `input` can be either "", - * "Argument[n]", "Argument[n1..n2]", "ReturnValue": + * element selected by the first 6 columns. An `input` can be a dot separated + * path consisting of either "", "Argument[n]", "Argument[n1..n2]", + * "ReturnValue", "Element", "WithoutElement", or "WithElement": * - "": Selects a write to the selected element in case this is a field. * - "Argument[n]": Selects an argument in a call to the selected element. * The arguments are zero-indexed, and `this` specifies the qualifier. @@ -44,9 +45,14 @@ * the given range. The range is inclusive at both ends. * - "ReturnValue": Selects a value being returned by the selected element. * This requires that the selected element is a method with a body. + * - "Element": Selects the collection elements of the selected element. + * - "WithoutElement": Selects the selected element but without + * its collection elements. + * - "WithElement": Selects the collection elements of the selected element. * - * An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter", - * "Parameter[n]", "Parameter[n1..n2]", or "ReturnValue": + * An `output` can be can be a dot separated path consisting of either "", + * "Argument[n]", "Argument[n1..n2]", "Parameter", "Parameter[n]", + * "Parameter[n1..n2]", "ReturnValue", or "Element": * - "": Selects a read of a selected field, or a selected parameter. * - "Argument[n]": Selects the post-update value of an argument in a call to the * selected element. That is, the value of the argument after the call returns. @@ -61,6 +67,7 @@ * - "Parameter[n1..n2]": Similar to "Parameter[n]" but selects any parameter * in the given range. The range is inclusive at both ends. * - "ReturnValue": Selects the return value of a call to the selected element. + * - "Element": Selects the collection elements of the selected element. * 8. The `kind` column is a tag that can be referenced from QL to determine to * which classes the interpreted elements should be added. For example, for * sources "remote" indicates a default remote flow source, and for summaries From ffd1456d67635681b7a3d006e959d002421c3407 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 4 Jul 2023 13:27:57 +0200 Subject: [PATCH 08/23] Java: Update MaD external documentation related to With and Without Element. --- .../customizing-library-models-for-java.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 950fdc7bf24..fab7b5f5cce 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -397,6 +397,8 @@ The following components are supported: - **SyntheticGlobal[**\ `name`\ **]** selects the synthetic global with name `name`. - **ArrayElement** selects the elements of an array. - **Element** selects the elements of a collection-like container. +- **WithoutElement** selects a collection-like container without its elements (input only). +- **WithElement** selects the elements of a collection-like container but not the container itself (input only). - **MapKey** selects the element keys of a map. - **MapValue** selects the element values of a map. From d3eb9c1325691866e4057cd1cdec0595fe824e90 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 4 Aug 2023 13:36:43 +0200 Subject: [PATCH 09/23] Java: Add release note and address review comments. --- .../customizing-library-models-for-java.rst | 4 ++-- java/ql/lib/change-notes/2023-08-04-mad-withoutelement.md | 4 ++++ java/ql/lib/ext/java.util.model.yml | 2 +- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-08-04-mad-withoutelement.md diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index fab7b5f5cce..37e1fb35450 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -397,8 +397,8 @@ The following components are supported: - **SyntheticGlobal[**\ `name`\ **]** selects the synthetic global with name `name`. - **ArrayElement** selects the elements of an array. - **Element** selects the elements of a collection-like container. -- **WithoutElement** selects a collection-like container without its elements (input only). -- **WithElement** selects the elements of a collection-like container but not the container itself (input only). +- **WithoutElement** selects a collection-like container without its elements. This is for input only. +- **WithElement** selects the elements of a collection-like container, but points to the container itself. This is for input only. - **MapKey** selects the element keys of a map. - **MapValue** selects the element values of a map. diff --git a/java/ql/lib/change-notes/2023-08-04-mad-withoutelement.md b/java/ql/lib/change-notes/2023-08-04-mad-withoutelement.md new file mode 100644 index 00000000000..f5e5cda8896 --- /dev/null +++ b/java/ql/lib/change-notes/2023-08-04-mad-withoutelement.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Add support for `WithElement` and `WithoutElement` for MaD access paths. \ No newline at end of file diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 88feefc7dd8..9816c0b9383 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -141,6 +141,7 @@ extensions: - ["java.util", "LinkedList", False, "LinkedList", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "List", True, "add", "(int,Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].WithElement", "Argument[this]", "value", "manual"] + - ["java.util", "List", True, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["java.util", "List", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["java.util", "List", True, "get", "(int)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "List", True, "listIterator", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] @@ -159,7 +160,6 @@ extensions: - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - ["java.util", "List", True, "subList", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["java.util", "List", True, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["java.util", "ListIterator", True, "add", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util", "ListIterator", True, "previous", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "ListIterator", True, "set", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 5100cfe4482..b7ef1410bfa 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -48,7 +48,8 @@ * - "Element": Selects the collection elements of the selected element. * - "WithoutElement": Selects the selected element but without * its collection elements. - * - "WithElement": Selects the collection elements of the selected element. + * - "WithElement": Selects the collection elements of the selected element, but + * points to the selected element. * * An `output` can be can be a dot separated path consisting of either "", * "Argument[n]", "Argument[n1..n2]", "Parameter", "Parameter[n]", From 92db7b047ca58330a7e2d2fd0da48bb412451939 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 7 Aug 2023 23:01:17 +0200 Subject: [PATCH 10/23] escape unicode chars in the output for the ReDoS queries --- .../ReDoS/PolynomialBackTracking.expected | 2 +- .../Security/CWE-400/ReDoS/ReDoS.expected | 7 +- .../query-tests/Security/CWE-400/ReDoS/tst.js | 4 +- .../Security/CWE-730-ReDoS/ReDoS.expected | 12 ++-- .../cwe-1333-exponential-redos/ReDoS.expected | 6 +- shared/regex/codeql/regex/nfa/NfaUtils.qll | 65 +++++++++++++++++-- 6 files changed, 78 insertions(+), 18 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected index d8bac89a913..f5d780e3190 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected @@ -445,7 +445,7 @@ | tst.js:146:15:146:21 | (\\d\|5)* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding ((\\d\|5)*)" | | tst.js:149:15:149:24 | (\\s\|[\\f])* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding ((\\s\|[\\f])*)" | | tst.js:152:15:152:28 | (\\s\|[\\v]\|\\\\v)* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding ((\\s\|[\\v]\|\\\\v)*)" | -| tst.js:155:15:155:24 | (\\f\|[\\f])* | Strings with many repetitions of '\u000c' can start matching anywhere after the start of the preceeding ((\\f\|[\\f])*)" | +| tst.js:155:15:155:24 | (\\f\|[\\f])* | Strings with many repetitions of '\\u000c' can start matching anywhere after the start of the preceeding ((\\f\|[\\f])*)" | | tst.js:158:15:158:22 | (\\W\|\\D)* | Strings with many repetitions of '/' can start matching anywhere after the start of the preceeding ((\\W\|\\D)*)" | | tst.js:161:15:161:22 | (\\S\|\\w)* | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ((\\S\|\\w)*)" | | tst.js:164:15:164:24 | (\\S\|[\\w])* | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ((\\S\|[\\w])*)" | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected index 674a0dcc29e..4586008491e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected @@ -123,9 +123,9 @@ | tst.js:137:15:137:21 | (\\w\|G)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'G'. | | tst.js:143:15:143:22 | (\\d\|\\w)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | tst.js:146:15:146:21 | (\\d\|5)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '5'. | -| tst.js:149:15:149:24 | (\\s\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000c'. | -| tst.js:152:15:152:28 | (\\s\|[\\v]\|\\\\v)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000b'. | -| tst.js:155:15:155:24 | (\\f\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000c'. | +| tst.js:149:15:149:24 | (\\s\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000c'. | +| tst.js:152:15:152:28 | (\\s\|[\\v]\|\\\\v)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000b'. | +| tst.js:155:15:155:24 | (\\f\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000c'. | | tst.js:158:15:158:22 | (\\W\|\\D)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '/'. | | tst.js:161:15:161:22 | (\\S\|\\w)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | tst.js:164:15:164:24 | (\\S\|[\\w])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | @@ -199,3 +199,4 @@ | tst.js:404:6:405:7 | (g\|gg)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'gg'. | | tst.js:407:125:407:127 | \\s* | This part of the regular expression may cause exponential backtracking on strings starting with '0/*' and containing many repetitions of ' ;0'. | | tst.js:411:15:411:19 | a{1,} | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. | +| tst.js:413:25:413:35 | (\\u0000\|.)+ | This part of the regular expression may cause exponential backtracking on strings starting with '\\n\\u0000' and containing many repetitions of '\\u0000'. | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js index 19fdd42dcad..3c88139fd3d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js @@ -408,4 +408,6 @@ var bad98 = /^(?:\*\/\*|[a-zA-Z0-9][a-zA-Z0-9!\#\$&\-\^_\.\+]{0,126}\/(?:\*|[a-z var good48 = /(\/(?:\/[\w.-]*)*){0,1}:([\w.-]+)/; -var bad99 = /(a{1,})*b/; \ No newline at end of file +var bad99 = /(a{1,})*b/; + +var unicode = /^\n\u0000(\u0000|.)+$/; \ No newline at end of file diff --git a/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected index 9a60667fd53..e6768bfaea0 100644 --- a/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected @@ -35,9 +35,9 @@ | redos.py:139:25:139:31 | (\\w\|G)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'G'. | | redos.py:145:25:145:32 | (\\d\|\\w)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | redos.py:148:25:148:31 | (\\d\|5)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '5'. | -| redos.py:151:25:151:34 | (\\s\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000c'. | -| redos.py:154:25:154:38 | (\\s\|[\\v]\|\\\\v)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000b'. | -| redos.py:157:25:157:34 | (\\f\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000c'. | +| redos.py:151:25:151:34 | (\\s\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000c'. | +| redos.py:154:25:154:38 | (\\s\|[\\v]\|\\\\v)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000b'. | +| redos.py:157:25:157:34 | (\\f\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000c'. | | redos.py:160:25:160:32 | (\\W\|\\D)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of ' '. | | redos.py:163:25:163:32 | (\\S\|\\w)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | redos.py:166:25:166:34 | (\\S\|[\\w])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | @@ -67,8 +67,8 @@ | redos.py:259:24:259:126 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\tthisisagoddamnlongstringforstresstestingthequery'. | | redos.py:262:24:262:87 | (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'thisisagoddamnlongstringforstresstestingthequery'. | | redos.py:262:78:262:80 | \\w+ | This part of the regular expression may cause exponential backtracking on strings starting with 'this' and containing many repetitions of '0querythis'. | -| redos.py:268:28:268:39 | ([\ufffd\ufffd]\|[\ufffd\ufffd])* | This part of the regular expression may cause exponential backtracking on strings starting with 'foo' and containing many repetitions of '\ufffd'. | -| redos.py:271:28:271:41 | ((\ufffd\|\ufffd)\|(\ufffd\|\ufffd))* | This part of the regular expression may cause exponential backtracking on strings starting with 'foo' and containing many repetitions of '\ufffd'. | +| redos.py:268:28:268:39 | ([\ufffd\ufffd]\|[\ufffd\ufffd])* | This part of the regular expression may cause exponential backtracking on strings starting with 'foo' and containing many repetitions of '\\ufffd'. | +| redos.py:271:28:271:41 | ((\ufffd\|\ufffd)\|(\ufffd\|\ufffd))* | This part of the regular expression may cause exponential backtracking on strings starting with 'foo' and containing many repetitions of '\\ufffd'. | | redos.py:274:31:274:32 | b+ | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'b'. | | redos.py:277:48:277:50 | \\s* | This part of the regular expression may cause exponential backtracking on strings starting with '<0\\t0=' and containing many repetitions of '""\\t0='. | | redos.py:283:26:283:27 | a+ | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. | @@ -103,5 +103,5 @@ | redos.py:385:24:385:30 | (\\d\|0)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | redos.py:386:26:386:32 | (\\d\|0)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | redos.py:391:15:391:25 | (\\u0061\|a)* | This part of the regular expression may cause exponential backtracking on strings starting with 'X' and containing many repetitions of 'a'. | -| unittests.py:5:17:5:23 | (\u00c6\|\\\u00c6)+ | This part of the regular expression may cause exponential backtracking on strings starting with 'X' and containing many repetitions of '\u00c6'. | +| unittests.py:5:17:5:23 | (\u00c6\|\\\u00c6)+ | This part of the regular expression may cause exponential backtracking on strings starting with 'X' and containing many repetitions of '\\u00c6'. | | unittests.py:9:16:9:24 | (?:.\|\\n)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\n'. | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.expected b/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.expected index ee274031bf0..f8fa2e9dc2e 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.expected @@ -33,9 +33,9 @@ | tst.rb:137:11:137:17 | (\\w\|G)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'G'. | | tst.rb:143:11:143:18 | (\\d\|\\w)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | tst.rb:146:11:146:17 | (\\d\|5)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '5'. | -| tst.rb:149:11:149:20 | (\\s\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000c'. | -| tst.rb:152:11:152:24 | (\\s\|[\\v]\|\\\\v)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000b'. | -| tst.rb:155:11:155:20 | (\\f\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\u000c'. | +| tst.rb:149:11:149:20 | (\\s\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000c'. | +| tst.rb:152:11:152:24 | (\\s\|[\\v]\|\\\\v)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000b'. | +| tst.rb:155:11:155:20 | (\\f\|[\\f])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\u000c'. | | tst.rb:158:11:158:18 | (\\W\|\\D)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of ' '. | | tst.rb:161:11:161:18 | (\\S\|\\w)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | | tst.rb:164:11:164:20 | (\\S\|[\\w])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0'. | diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index 005228e8970..9592bada015 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -1305,10 +1305,67 @@ module Make { bindingset[s] private string escape(string s) { result = - s.replaceAll("\\", "\\\\") - .replaceAll("\n", "\\n") - .replaceAll("\r", "\\r") - .replaceAll("\t", "\\t") + escapeUnicodeString(s.replaceAll("\\", "\\\\") + .replaceAll("\n", "\\n") + .replaceAll("\r", "\\r") + .replaceAll("\t", "\\t")) + } + + /** + * Gets a string where the unicode characters in `s` have been escaped. + */ + bindingset[s] + private string escapeUnicodeString(string s) { + result = concat(int i, string char | char = escapeUnicodeChar(s.charAt(i)) | char order by i) + } + + /** + * Gets a unicode escaped string for `char`. + * If `char` is a printable char, then `char` is returned. + */ + bindingset[char] + private string escapeUnicodeChar(string char) { + if isPrintable(char) + then result = char + else result = "\\u" + to4digitNumber(toHex(any(int i | i.toUnicode() = char))) + } + + /** + * Gets a string representation of `number` in hexadecimal. + * Works for the first 200000 numbers, which is enough for every unicode character. + */ + private string toHex(int number) { + number = [0 .. 200000] and + if number <= 9 + then result = number + "" + else + if number <= 15 + then result = "abcdef".charAt(number - 10) + else result = toHex(number / 16) + toHex(number % 16) + } + + /** Gets a string where 0 has been prepended to `num` until it has length 4. */ + bindingset[num] + private string to4digitNumber(string num) { + if num.length() >= 4 + then result = num + else + if num.length() = 3 + then result = "0" + num + else + if num.length() = 2 + then result = "00" + num + else + if num.length() = 1 + then result = "000" + num + else result = "0000" + } + + /** Holds if `char` is easily printable char, or whitespace. */ + private predicate isPrintable(string char) { + exists(ascii(char)) + or + char = "\n\r\t".charAt(_) } /** From 03fbd387df839dfde5dbbfa9181d223d1c390f30 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 8 Aug 2023 09:08:39 +0200 Subject: [PATCH 11/23] way better hex conversion --- shared/regex/codeql/regex/nfa/NfaUtils.qll | 37 ++++++---------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index 9592bada015..cc89cea77de 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -1327,38 +1327,19 @@ module Make { private string escapeUnicodeChar(string char) { if isPrintable(char) then result = char - else result = "\\u" + to4digitNumber(toHex(any(int i | i.toUnicode() = char))) + else result = "\\u" + to4digitHex(any(int i | i.toUnicode() = char)) } /** - * Gets a string representation of `number` in hexadecimal. - * Works for the first 200000 numbers, which is enough for every unicode character. + * Gets a 4-digit hex representation of `i`. */ - private string toHex(int number) { - number = [0 .. 200000] and - if number <= 9 - then result = number + "" - else - if number <= 15 - then result = "abcdef".charAt(number - 10) - else result = toHex(number / 16) + toHex(number % 16) - } - - /** Gets a string where 0 has been prepended to `num` until it has length 4. */ - bindingset[num] - private string to4digitNumber(string num) { - if num.length() >= 4 - then result = num - else - if num.length() = 3 - then result = "0" + num - else - if num.length() = 2 - then result = "00" + num - else - if num.length() = 1 - then result = "000" + num - else result = "0000" + bindingset[i] + string to4digitHex(int i) { + result = + "0123456789abcdef".charAt(i.bitShiftRight(12).bitAnd(15)) + + "0123456789abcdef".charAt(i.bitShiftRight(8).bitAnd(15)) + + "0123456789abcdef".charAt(i.bitShiftRight(4).bitAnd(15)) + + "0123456789abcdef".charAt(i.bitAnd(15)) } /** Holds if `char` is easily printable char, or whitespace. */ From 0ed724eb13090bf8a040d0c2a896c22f4430c673 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 7 Aug 2023 09:50:30 +0200 Subject: [PATCH 12/23] Java: Make a flow summary for Set.clear using WithoutElement and introduce appropriate tests. --- java/ql/lib/ext/java.util.model.yml | 2 +- .../ql/test/library-tests/dataflow/collections/B.java | 11 +++++++++++ .../TopJdkApisTest/TopJdkApisTest.expected | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 9816c0b9383..feb7ff473bd 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -314,6 +314,7 @@ extensions: - ["java.util", "Scanner", True, "useLocale", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.util", "Scanner", True, "useRadix", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.util", "Set", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["java.util", "Set", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] - ["java.util", "Set", False, "of", "(Object,Object)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] - ["java.util", "Set", False, "of", "(Object,Object,Object)", "", "Argument[0..2]", "ReturnValue.Element", "value", "manual"] @@ -427,7 +428,6 @@ extensions: - ["java.util", "Iterator", "remove", "()", "summary", "manual"] - ["java.util", "List", "remove", "(Object)", "summary", "manual"] - ["java.util", "Map", "clear", "()", "summary", "manual"] - - ["java.util", "Set", "clear", "()", "summary", "manual"] - ["java.util", "Set", "remove", "(Object)", "summary", "manual"] - ["java.util", "Set", "removeAll", "(Collection)", "summary", "manual"] diff --git a/java/ql/test/library-tests/dataflow/collections/B.java b/java/ql/test/library-tests/dataflow/collections/B.java index ec43b30c0fd..7d9c418c162 100644 --- a/java/ql/test/library-tests/dataflow/collections/B.java +++ b/java/ql/test/library-tests/dataflow/collections/B.java @@ -9,6 +9,7 @@ public class B { static void sink(Object obj) { } static Object[] storeArrayElement(Object obj) { return new Object[] {obj}; } + static Set storeSetElement(Object obj) { return Set.of(obj); } static Object readArrayElement(Object[] obj) { return obj[0]; } static boolean readArrayElement(boolean[] obj) { return obj[0]; } @@ -1232,6 +1233,16 @@ public class B { Map out = null; Object[] in = storeArrayElement(storeMapValue(source())); out = Map.ofEntries((Map.Entry[])in); sink(readMapValue(out)); // $ hasValueFlow } + { + // "java.util;Set;true;clear;;;Argument[this].WithoutElement;Argument[this];value;manual" + Set out = null; + Set in = storeSetElement(source()); out = in; out.clear(); sink(readElement(out)); // No flow + } + { + // "java.util;Set;true;clear;;;Argument[this].WithoutElement;Argument[this];value;manual" + Set out = null; + Set in = (Set)source(); out = in; out.clear(); sink(out); // $ hasValueFlow + } { // "java.util;Set;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", Set out = null; diff --git a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected index 37600f1f707..a092100b6a7 100644 --- a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected +++ b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected @@ -13,7 +13,7 @@ | java.time | 0 | 0 | 0 | 17 | 17 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.time.chrono | 0 | 0 | 0 | 1 | 1 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.time.format | 0 | 0 | 0 | 2 | 2 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | -| java.util | 0 | 0 | 85 | 67 | 152 | 0.5592105263157895 | 0.0 | 0.5592105263157895 | 0.0 | NaN | 0.4407894736842105 | +| java.util | 0 | 0 | 86 | 66 | 152 | 0.5657894736842105 | 0.0 | 0.5657894736842105 | 0.0 | NaN | 0.4342105263157895 | | java.util.concurrent | 0 | 0 | 9 | 9 | 18 | 0.5 | 0.0 | 0.5 | 0.0 | NaN | 0.5 | | java.util.concurrent.atomic | 0 | 0 | 2 | 11 | 13 | 0.15384615384615385 | 0.0 | 0.15384615384615385 | 0.0 | NaN | 0.8461538461538461 | | java.util.concurrent.locks | 0 | 0 | 0 | 2 | 2 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | From cebaca328e4cc90cc3f9c5de9afef7428447d83b Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Fri, 28 Jul 2023 15:05:45 +0200 Subject: [PATCH 13/23] Swift: 'ParsedSequence' lacks proper types and yields 'Unresolved' AST nodes --- .../extractor/translators/StmtTranslator.cpp | 2 +- .../test/library-tests/ast/PrintAst.expected | 47 +++++++++++-------- .../controlflow/graph/Cfg.expected | 8 +++- .../CONSISTENCY/CfgConsistency.expected | 3 -- .../CONSISTENCY/CfgConsistency.expected | 2 - 5 files changed, 36 insertions(+), 26 deletions(-) delete mode 100644 swift/ql/test/library-tests/dataflow/flowsources/CONSISTENCY/CfgConsistency.expected delete mode 100644 swift/ql/test/library-tests/dataflow/taint/libraries/CONSISTENCY/CfgConsistency.expected diff --git a/swift/extractor/translators/StmtTranslator.cpp b/swift/extractor/translators/StmtTranslator.cpp index 6ff54bd8edf..b7776a104b7 100644 --- a/swift/extractor/translators/StmtTranslator.cpp +++ b/swift/extractor/translators/StmtTranslator.cpp @@ -73,7 +73,7 @@ codeql::ForEachStmt StmtTranslator::translateForEachStmt(const swift::ForEachStm auto entry = dispatcher.createEntry(stmt); fillLabeledStmt(stmt, entry); entry.body = dispatcher.fetchLabel(stmt.getBody()); - entry.sequence = dispatcher.fetchLabel(stmt.getParsedSequence()); + entry.sequence = dispatcher.fetchLabel(stmt.getTypeCheckedSequence()); entry.pattern = dispatcher.fetchLabel(stmt.getPattern()); entry.where = dispatcher.fetchOptionalLabel(stmt.getWhere()); return entry; diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index 4f962606e1b..b95a33ac211 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -703,15 +703,18 @@ cfg.swift: # 155| Type = Int? # 138| getElement(0): [ForEachStmt] for ... in ... { ... } # 138| getPattern(): [AnyPattern] _ -# 138| getSequence(): [BinaryExpr] ... ....(_:_:) ... -# 138| getFunction(): [MethodLookupExpr] ....(_:_:) -# 138| getBase(): [TypeExpr] Int.Type -# 138| getTypeRepr(): [TypeRepr] Int -# 138| getMethodRef(): [DeclRefExpr] ...(_:_:) -# 138| getArgument(0): [Argument] : 0 -# 138| getExpr(): [IntegerLiteralExpr] 0 -# 138| getArgument(1): [Argument] : 10 -# 138| getExpr(): [IntegerLiteralExpr] 10 +# 138| getSequence(): [CallExpr] call to makeIterator() +# 138| getFunction(): [MethodLookupExpr] .makeIterator() +# 138| getBase(): [BinaryExpr] ... ....(_:_:) ... +# 138| getFunction(): [MethodLookupExpr] ....(_:_:) +# 138| getBase(): [TypeExpr] Int.Type +# 138| getTypeRepr(): [TypeRepr] Int +# 138| getMethodRef(): [DeclRefExpr] ...(_:_:) +# 138| getArgument(0): [Argument] : 0 +# 138| getExpr(): [IntegerLiteralExpr] 0 +# 138| getArgument(1): [Argument] : 10 +# 138| getExpr(): [IntegerLiteralExpr] 10 +#-----| getMethodRef(): [DeclRefExpr] makeIterator() # 138| getBody(): [BraceStmt] { ... } # 140| getElement(1): [SwitchStmt] switch x { ... } # 140| getExpr(): [DeclRefExpr] x @@ -6493,15 +6496,18 @@ statements.swift: # 9| Type = Int # 2| getElement(0): [ForEachStmt] for ... in ... { ... } # 2| getPattern(): [NamedPattern] i -# 2| getSequence(): [BinaryExpr] ... ....(_:_:) ... -# 2| getFunction(): [MethodLookupExpr] ....(_:_:) -# 2| getBase(): [TypeExpr] Int.Type -# 2| getTypeRepr(): [TypeRepr] Int -# 2| getMethodRef(): [DeclRefExpr] ...(_:_:) -# 2| getArgument(0): [Argument] : 1 -# 2| getExpr(): [IntegerLiteralExpr] 1 -# 2| getArgument(1): [Argument] : 5 -# 2| getExpr(): [IntegerLiteralExpr] 5 +# 2| getSequence(): [CallExpr] call to makeIterator() +# 2| getFunction(): [MethodLookupExpr] .makeIterator() +# 2| getBase(): [BinaryExpr] ... ....(_:_:) ... +# 2| getFunction(): [MethodLookupExpr] ....(_:_:) +# 2| getBase(): [TypeExpr] Int.Type +# 2| getTypeRepr(): [TypeRepr] Int +# 2| getMethodRef(): [DeclRefExpr] ...(_:_:) +# 2| getArgument(0): [Argument] : 1 +# 2| getExpr(): [IntegerLiteralExpr] 1 +# 2| getArgument(1): [Argument] : 5 +# 2| getExpr(): [IntegerLiteralExpr] 5 +#-----| getMethodRef(): [DeclRefExpr] makeIterator() # 2| getBody(): [BraceStmt] { ... } # 3| getElement(0): [IfStmt] if ... then { ... } else { ... } # 3| getCondition(): [StmtCondition] StmtCondition @@ -6914,7 +6920,10 @@ statements.swift: # 71| getBody(): [BraceStmt] { ... } # 71| getElement(0): [ForEachStmt] for ... in ... where ... { ... } # 71| getPattern(): [NamedPattern] number -# 71| getSequence(): [DeclRefExpr] numbers +# 71| getSequence(): [CallExpr] call to makeIterator() +# 71| getFunction(): [MethodLookupExpr] .makeIterator() +# 71| getBase(): [DeclRefExpr] numbers +#-----| getMethodRef(): [DeclRefExpr] makeIterator() # 71| getWhere(): [BinaryExpr] ... .==(_:_:) ... # 71| getFunction(): [MethodLookupExpr] .==(_:_:) # 71| getBase(): [TypeExpr] Int.Type diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 4f87ff785ed..844b55de90e 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -1422,7 +1422,7 @@ cfg.swift: #-----| -> x # 137| x -#-----| -> ....(_:_:) +#-----| -> .makeIterator() # 138| for ... in ... { ... } #-----| non-empty -> _ @@ -1435,6 +1435,12 @@ cfg.swift: #-----| -> 10 # 138| ... ....(_:_:) ... +#-----| -> call to makeIterator() + +# 138| .makeIterator() +#-----| -> ....(_:_:) + +# 138| call to makeIterator() #-----| -> for ... in ... { ... } # 138| ....(_:_:) diff --git a/swift/ql/test/library-tests/dataflow/flowsources/CONSISTENCY/CfgConsistency.expected b/swift/ql/test/library-tests/dataflow/flowsources/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index ac216c004f2..00000000000 --- a/swift/ql/test/library-tests/dataflow/flowsources/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,3 +0,0 @@ -deadEnd -| customurlschemes.swift:94:59:94:76 | options | -| customurlschemes.swift:133:59:133:76 | options | diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/CONSISTENCY/CfgConsistency.expected b/swift/ql/test/library-tests/dataflow/taint/libraries/CONSISTENCY/CfgConsistency.expected deleted file mode 100644 index 34ad2196338..00000000000 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/CONSISTENCY/CfgConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -deadEnd -| url.swift:493:2:493:28 | call to sink(any:) | From 0391e063ca5f0c5c86476e293d808722416393a1 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 8 Aug 2023 21:10:58 +0200 Subject: [PATCH 14/23] move `to4digitHex` to `Numbers.qll` --- shared/regex/codeql/regex/nfa/NfaUtils.qll | 13 +------------ shared/regex/qlpack.yml | 1 + shared/util/codeql/util/Numbers.qll | 12 ++++++++++++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index cc89cea77de..aadfd533944 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -3,6 +3,7 @@ */ private import codeql.regex.RegexTreeView +private import codeql.util.Numbers /** * Classes and predicates that create an NFA and various algorithms for working with it. @@ -1330,18 +1331,6 @@ module Make { else result = "\\u" + to4digitHex(any(int i | i.toUnicode() = char)) } - /** - * Gets a 4-digit hex representation of `i`. - */ - bindingset[i] - string to4digitHex(int i) { - result = - "0123456789abcdef".charAt(i.bitShiftRight(12).bitAnd(15)) + - "0123456789abcdef".charAt(i.bitShiftRight(8).bitAnd(15)) + - "0123456789abcdef".charAt(i.bitShiftRight(4).bitAnd(15)) + - "0123456789abcdef".charAt(i.bitAnd(15)) - } - /** Holds if `char` is easily printable char, or whitespace. */ private predicate isPrintable(string char) { exists(ascii(char)) diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 7af709c09df..e20924bc67b 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -3,4 +3,5 @@ version: 0.1.2-dev groups: shared library: true dependencies: + codeql/util: ${workspace} warnOnImplicitThis: true diff --git a/shared/util/codeql/util/Numbers.qll b/shared/util/codeql/util/Numbers.qll index 2c12438300d..edbb0a452eb 100644 --- a/shared/util/codeql/util/Numbers.qll +++ b/shared/util/codeql/util/Numbers.qll @@ -100,6 +100,18 @@ private int toHex(string hex) { result = 15 and hex = ["f", "F"] } +/** + * Gets a 4-digit hex representation of `i`. + */ +bindingset[i] +string to4digitHex(int i) { + result = + "0123456789abcdef".charAt(i.bitShiftRight(12).bitAnd(15)) + + "0123456789abcdef".charAt(i.bitShiftRight(8).bitAnd(15)) + + "0123456789abcdef".charAt(i.bitShiftRight(4).bitAnd(15)) + + "0123456789abcdef".charAt(i.bitAnd(15)) +} + /** * Gets the value of 16 to the power of `n`. Holds only for `n` in the range * 0..7 (inclusive). From 859e1bfabc5b8efeaa681a56700ccaa90d2ba2a5 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 8 Aug 2023 21:11:59 +0200 Subject: [PATCH 15/23] add constraint that i should be between 0 and 65535 --- shared/util/codeql/util/Numbers.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/util/codeql/util/Numbers.qll b/shared/util/codeql/util/Numbers.qll index edbb0a452eb..b7ffc7c8db2 100644 --- a/shared/util/codeql/util/Numbers.qll +++ b/shared/util/codeql/util/Numbers.qll @@ -105,6 +105,8 @@ private int toHex(string hex) { */ bindingset[i] string to4digitHex(int i) { + i >= 0 and + i <= 65535 and result = "0123456789abcdef".charAt(i.bitShiftRight(12).bitAnd(15)) + "0123456789abcdef".charAt(i.bitShiftRight(8).bitAnd(15)) + From 0bce42410a6b2a8bc6ee569368fe3ea350cc9685 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 8 Aug 2023 22:14:51 +0200 Subject: [PATCH 16/23] support arbitrary codepoints in NfaUtils.qll --- .../Security/CWE-400/ReDoS/ReDoS.expected | 1 + .../query-tests/Security/CWE-400/ReDoS/tst.js | 4 +- shared/regex/codeql/regex/nfa/NfaUtils.qll | 60 ++++++++++++++----- shared/util/codeql/util/Numbers.qll | 24 ++++++-- 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected index 4586008491e..662dadaaa5b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/ReDoS.expected @@ -200,3 +200,4 @@ | tst.js:407:125:407:127 | \\s* | This part of the regular expression may cause exponential backtracking on strings starting with '0/*' and containing many repetitions of ' ;0'. | | tst.js:411:15:411:19 | a{1,} | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. | | tst.js:413:25:413:35 | (\\u0000\|.)+ | This part of the regular expression may cause exponential backtracking on strings starting with '\\n\\u0000' and containing many repetitions of '\\u0000'. | +| tst.js:415:44:415:57 | (\ud83d\ude80\|.)+ | This part of the regular expression may cause exponential backtracking on strings starting with '\\n\\u{1f680}' and containing many repetitions of '\\u{1f680}'. | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js index 3c88139fd3d..ef82076e702 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js @@ -410,4 +410,6 @@ var good48 = /(\/(?:\/[\w.-]*)*){0,1}:([\w.-]+)/; var bad99 = /(a{1,})*b/; -var unicode = /^\n\u0000(\u0000|.)+$/; \ No newline at end of file +var unicode = /^\n\u0000(\u0000|.)+$/; + +var largeUnicode = new RegExp("^\n\u{1F680}(\u{1F680}|.)+X$"); \ No newline at end of file diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index aadfd533944..650516fd4cf 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -18,6 +18,20 @@ module Make { exists(int code | code = ascii(c) | code + 1 = ascii(result)) } + /** + * Gets the `i`th codepoint in `s`. + */ + bindingset[s] + private string getCodepointAt(string s, int i) { result = s.regexpFind("(.|\\s)", i, _) } + + /** + * Gets the length of `s` in codepoints. + */ + bindingset[str] + private int getCodepointLength(string str) { + result = max(int m | exists(str.regexpFind("(.|\\s)", m - 1, _)) or m = 0) + } + /** * Gets an approximation for the ASCII code for `char`. * Only the easily printable chars are included (so no newline, tab, null, etc). @@ -190,17 +204,17 @@ module Make { /** An input symbol corresponding to character `c`. */ Char(string c) { c = - any(RegexpCharacterConstant cc | - cc instanceof RelevantRegExpTerm and - not isIgnoreCase(cc.getRootTerm()) - ).getValue().charAt(_) + getCodepointAt(any(RegexpCharacterConstant cc | + cc instanceof RelevantRegExpTerm and + not isIgnoreCase(cc.getRootTerm()) + ).getValue(), _) or // normalize everything to lower case if the regexp is case insensitive c = any(RegexpCharacterConstant cc, string char | cc instanceof RelevantRegExpTerm and isIgnoreCase(cc.getRootTerm()) and - char = cc.getValue().charAt(_) + char = getCodepointAt(cc.getValue(), _) | char.toLowerCase() ) @@ -396,7 +410,7 @@ module Make { string getARelevantChar() { exists(ascii(result)) or - exists(RegexpCharacterConstant c | result = c.getValue().charAt(_)) + exists(RegexpCharacterConstant c | result = getCodepointAt(c.getValue(), _)) or classEscapeMatches(_, result) } @@ -702,16 +716,16 @@ module Make { q1 = Match(s, i) and ( not isIgnoreCase(s.getRootTerm()) and - lbl = Char(s.getValue().charAt(i)) + lbl = Char(getCodepointAt(s.getValue(), i)) or // normalize everything to lower case if the regexp is case insensitive isIgnoreCase(s.getRootTerm()) and - exists(string c | c = s.getValue().charAt(i) | lbl = Char(c.toLowerCase())) + exists(string c | c = getCodepointAt(s.getValue(), i) | lbl = Char(c.toLowerCase())) ) and ( q2 = Match(s, i + 1) or - s.getValue().length() = i + 1 and + getCodepointLength(s.getValue()) = i + 1 and q2 = after(s) ) ) @@ -812,7 +826,7 @@ module Make { Match(RelevantRegExpTerm t, int i) { i = 0 or - exists(t.(RegexpCharacterConstant).getValue().charAt(i)) + exists(getCodepointAt(t.(RegexpCharacterConstant).getValue(), i)) } or /** * An accept state, where exactly the given input string is accepted. @@ -1105,7 +1119,9 @@ module Make { */ predicate reachesOnlyRejectableSuffixes(State fork, string w) { isReDoSCandidate(fork, w) and - forex(State next | next = process(fork, w, w.length() - 1) | isLikelyRejectable(next)) and + forex(State next | next = process(fork, w, getCodepointLength(w) - 1) | + isLikelyRejectable(next) + ) and not getProcessPrevious(fork, _, w) = acceptsAnySuffix() // we stop `process(..)` early if we can, check here if it happened. } @@ -1215,6 +1231,12 @@ module Make { exists(string char | char = ["|", "\n", "Z"] | not deltaClosedChar(s, char, _)) } + // `process` can't use pragma[inline] predicates. So a materialized version of `getCodepointAt` is needed. + private string getCodePointAtForProcess(string str, int i) { + result = getCodepointAt(str, i) and + exists(getProcessPrevious(_, _, str)) + } + /** * Gets a state that can be reached from pumpable `fork` consuming all * chars in `w` any number of times followed by the first `i+1` characters of `w`. @@ -1224,7 +1246,7 @@ module Make { exists(State prev | prev = getProcessPrevious(fork, i, w) | not prev = acceptsAnySuffix() and // we stop `process(..)` early if we can. If the successor accepts any suffix, then we know it can never be rejected. exists(string char, InputSymbol sym | - char = w.charAt(i) and + char = getCodePointAtForProcess(w, i) and deltaClosed(prev, sym, result) and // noopt to prevent joining `prev` with all possible `chars` that could transition away from `prev`. // Instead only join with the set of `chars` where a relevant `InputSymbol` has already been found. @@ -1246,7 +1268,7 @@ module Make { or // repeat until fixpoint i = 0 and - result = process(fork, w, w.length() - 1) + result = process(fork, w, getCodepointLength(w) - 1) ) } @@ -1262,7 +1284,9 @@ module Make { /** * Gets a `char` that occurs in a `pump` string. */ - private string getAProcessChar() { result = any(string s | isReDoSCandidate(_, s)).charAt(_) } + private string getAProcessChar() { + result = getCodepointAt(any(string s | isReDoSCandidate(_, s)), _) + } } /** @@ -1317,7 +1341,8 @@ module Make { */ bindingset[s] private string escapeUnicodeString(string s) { - result = concat(int i, string char | char = escapeUnicodeChar(s.charAt(i)) | char order by i) + result = + concat(int i, string char | char = escapeUnicodeChar(getCodepointAt(s, i)) | char order by i) } /** @@ -1328,7 +1353,10 @@ module Make { private string escapeUnicodeChar(string char) { if isPrintable(char) then result = char - else result = "\\u" + to4digitHex(any(int i | i.toUnicode() = char)) + else + if exists(to4digitHex(any(int i | i.toUnicode() = char))) + then result = "\\u" + to4digitHex(any(int i | i.toUnicode() = char)) + else result = "\\u{" + toHex(any(int i | i.toUnicode() = char)) + "}" } /** Holds if `char` is easily printable char, or whitespace. */ diff --git a/shared/util/codeql/util/Numbers.qll b/shared/util/codeql/util/Numbers.qll index b7ffc7c8db2..050f3c023f1 100644 --- a/shared/util/codeql/util/Numbers.qll +++ b/shared/util/codeql/util/Numbers.qll @@ -50,7 +50,7 @@ int parseHexInt(string hex) { sum(int index, string c | c = stripped.charAt(index) | - sixteenToThe(stripped.length() - 1 - index) * toHex(c) + sixteenToThe(stripped.length() - 1 - index) * charToHex(c) ) ) } @@ -83,7 +83,7 @@ int parseOctalInt(string octal) { } /** Gets the integer value of the `hex` char. */ -private int toHex(string hex) { +private int charToHex(string hex) { hex = [0 .. 9].toString() and result = hex.toInt() or @@ -107,11 +107,23 @@ bindingset[i] string to4digitHex(int i) { i >= 0 and i <= 65535 and + exists(string hex | hex = toHex(i) | + result = concat(int zeroes | zeroes = [1 .. 4 - hex.length()] | "0") + hex + ) +} + +/** + * Gets a hex representation of `i`. + */ +bindingset[i] +string toHex(int i) { result = - "0123456789abcdef".charAt(i.bitShiftRight(12).bitAnd(15)) + - "0123456789abcdef".charAt(i.bitShiftRight(8).bitAnd(15)) + - "0123456789abcdef".charAt(i.bitShiftRight(4).bitAnd(15)) + - "0123456789abcdef".charAt(i.bitAnd(15)) + // make the number with lots of preceding zeroes, then remove all preceding zeroes in a post-processing step + concat(int shift | + shift in [28, 24, 20, 16, 12, 8, 4, 0] + | + "0123456789abcdef".charAt(i.bitShiftRight(shift).bitAnd(15)) order by shift desc + ).regexpReplaceAll("^0*", "") } /** From fe542565c37e96487471ced0c47b15ad22b4942a Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 9 Aug 2023 12:39:48 +0200 Subject: [PATCH 17/23] fix performance --- shared/regex/codeql/regex/nfa/NfaUtils.qll | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index 650516fd4cf..62ecf1e7bba 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -29,7 +29,7 @@ module Make { */ bindingset[str] private int getCodepointLength(string str) { - result = max(int m | exists(str.regexpFind("(.|\\s)", m - 1, _)) or m = 0) + result = str.regexpReplaceAll("(.|\\s)", "x").length() } /** @@ -708,6 +708,12 @@ module Make { ) } + pragma[noinline] + private int getCodepointLengthForState(string s) { + result = getCodepointLength(s) and + s = any(RegexpCharacterConstant reg).getValue() + } + /** * Holds if the NFA has a transition from `q1` to `q2` labelled with `lbl`. */ @@ -725,7 +731,7 @@ module Make { ( q2 = Match(s, i + 1) or - getCodepointLength(s.getValue()) = i + 1 and + getCodepointLengthForState(s.getValue()) = i + 1 and q2 = after(s) ) ) @@ -1119,7 +1125,7 @@ module Make { */ predicate reachesOnlyRejectableSuffixes(State fork, string w) { isReDoSCandidate(fork, w) and - forex(State next | next = process(fork, w, getCodepointLength(w) - 1) | + forex(State next | next = process(fork, w, getCodepointLengthForCandidate(w) - 1) | isLikelyRejectable(next) ) and not getProcessPrevious(fork, _, w) = acceptsAnySuffix() // we stop `process(..)` early if we can, check here if it happened. @@ -1232,9 +1238,10 @@ module Make { } // `process` can't use pragma[inline] predicates. So a materialized version of `getCodepointAt` is needed. + pragma[noinline] private string getCodePointAtForProcess(string str, int i) { result = getCodepointAt(str, i) and - exists(getProcessPrevious(_, _, str)) + isReDoSCandidate(_, str) } /** @@ -1255,6 +1262,12 @@ module Make { ) } + pragma[noinline] + private int getCodepointLengthForCandidate(string s) { + result = getCodepointLength(s) and + isReDoSCandidate(_, s) + } + /** * Gets a state that can be reached from pumpable `fork` consuming all * chars in `w` any number of times followed by the first `i` characters of `w`. @@ -1268,7 +1281,7 @@ module Make { or // repeat until fixpoint i = 0 and - result = process(fork, w, getCodepointLength(w) - 1) + result = process(fork, w, getCodepointLengthForCandidate(w) - 1) ) } From 77fca277fee81eac233754c04618cffaeb884ed5 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 10 Aug 2023 10:10:32 +0200 Subject: [PATCH 18/23] Ruby: Improve desugaring of `for` loops --- ruby/ql/lib/codeql/ruby/ast/Operation.qll | 4 +- ruby/ql/lib/codeql/ruby/ast/internal/AST.qll | 48 +- .../codeql/ruby/ast/internal/Operation.qll | 20 + .../codeql/ruby/ast/internal/Synthesis.qll | 149 +++-- .../library-tests/ast/AstDesugar.expected | 520 +++++++++++------- .../test/library-tests/ast/ValueText.expected | 24 + .../library-tests/ast/calls/calls.expected | 10 + .../ast/control/ConditionalExpr.expected | 6 + .../ast/control/ControlExpr.expected | 6 + .../controlflow/graph/Cfg.expected | 32 +- .../controlflow/graph/Nodes.expected | 3 + .../dataflow/local/DataflowStep.expected | 20 +- .../dataflow/local/Nodes.expected | 9 + .../dataflow/local/TaintStep.expected | 29 +- .../test/library-tests/variables/ssa.expected | 7 + .../variables/varaccess.expected | 4 + 16 files changed, 621 insertions(+), 270 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/Operation.qll b/ruby/ql/lib/codeql/ruby/ast/Operation.qll index 1efab2b4515..e5c68b72c8f 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Operation.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Operation.qll @@ -48,7 +48,7 @@ class UnaryLogicalOperation extends UnaryOperation, TUnaryLogicalOperation { } * not params.empty? * ``` */ -class NotExpr extends UnaryLogicalOperation, TNotExpr { +class NotExpr extends UnaryLogicalOperation instanceof NotExprImpl { final override string getAPrimaryQlClass() { result = "NotExpr" } } @@ -118,7 +118,7 @@ class ComplementExpr extends UnaryBitwiseOperation, TComplementExpr { * defined? some_method * ``` */ -class DefinedExpr extends UnaryOperation, TDefinedExpr { +class DefinedExpr extends UnaryOperation instanceof DefinedExprImpl { final override string getAPrimaryQlClass() { result = "DefinedExpr" } } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll b/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll index 4e2853e3a35..91f20773917 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll @@ -123,7 +123,8 @@ private module Cached { TConstantWriteAccessSynth(Ast::AstNode parent, int i, string value) { mkSynthChild(ConstantWriteAccessKind(value), parent, i) } or - TDefinedExpr(Ruby::Unary g) { g instanceof @ruby_unary_definedquestion } or + TDefinedExprReal(Ruby::Unary g) { g instanceof @ruby_unary_definedquestion } or + TDefinedExprSynth(Ast::AstNode parent, int i) { mkSynthChild(DefinedExprKind(), parent, i) } or TDelimitedSymbolLiteral(Ruby::DelimitedSymbol g) or TDestructuredLeftAssignment(Ruby::DestructuredLeftAssignment g) { not strictcount(int i | exists(g.getParent().(Ruby::LeftAssignmentList).getChild(i))) = 1 @@ -228,7 +229,8 @@ private module Cached { TNilLiteralReal(Ruby::Nil g) or TNilLiteralSynth(Ast::AstNode parent, int i) { mkSynthChild(NilLiteralKind(), parent, i) } or TNoRegExpMatchExpr(Ruby::Binary g) { g instanceof @ruby_binary_bangtilde } or - TNotExpr(Ruby::Unary g) { g instanceof @ruby_unary_bang or g instanceof @ruby_unary_not } or + TNotExprReal(Ruby::Unary g) { g instanceof @ruby_unary_bang or g instanceof @ruby_unary_not } or + TNotExprSynth(Ast::AstNode parent, int i) { mkSynthChild(NotExprKind(), parent, i) } or TOptionalParameter(Ruby::OptionalParameter g) or TPair(Ruby::Pair g) or TParenthesizedExpr(Ruby::ParenthesizedStatements g) or @@ -354,21 +356,21 @@ private module Cached { TBitwiseOrExprReal or TBitwiseXorExprReal or TBlockArgument or TBlockParameter or TBraceBlockReal or TBreakStmt or TCaseEqExpr or TCaseExpr or TCaseMatchReal or TCharacterLiteral or TClassDeclaration or TClassVariableAccessReal or TComplementExpr or - TComplexLiteral or TDefinedExpr or TDelimitedSymbolLiteral or TDestructuredLeftAssignment or - TDestructuredParameter or TDivExprReal or TDo or TDoBlock or TElementReference or - TElseReal or TElsif or TEmptyStmt or TEncoding or TEndBlock or TEnsure or TEqExpr or - TExponentExprReal or TFalseLiteral or TFile or TFindPattern or TFloatLiteral or TForExpr or - TForwardParameter or TForwardArgument or TGEExpr or TGTExpr or TGlobalVariableAccessReal or - THashKeySymbolLiteral or THashLiteral or THashPattern or THashSplatExpr or - THashSplatNilParameter or THashSplatParameter or THereDoc or TIdentifierMethodCall or - TIfReal or TIfModifierExpr or TInClauseReal or TInstanceVariableAccessReal or - TIntegerLiteralReal or TKeywordParameter or TLEExpr or TLShiftExprReal or TLTExpr or - TLambda or TLeftAssignmentList or TLine or TLocalVariableAccessReal or - TLogicalAndExprReal or TLogicalOrExprReal or TMethod or TMatchPattern or - TModuleDeclaration or TModuloExprReal or TMulExprReal or TNEExpr or TNextStmt or - TNilLiteralReal or TNoRegExpMatchExpr or TNotExpr or TOptionalParameter or TPair or - TParenthesizedExpr or TParenthesizedPattern or TRShiftExprReal or TRangeLiteralReal or - TRationalLiteral or TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or + TComplexLiteral or TDefinedExprReal or TDelimitedSymbolLiteral or + TDestructuredLeftAssignment or TDestructuredParameter or TDivExprReal or TDo or TDoBlock or + TElementReference or TElseReal or TElsif or TEmptyStmt or TEncoding or TEndBlock or + TEnsure or TEqExpr or TExponentExprReal or TFalseLiteral or TFile or TFindPattern or + TFloatLiteral or TForExpr or TForwardParameter or TForwardArgument or TGEExpr or TGTExpr or + TGlobalVariableAccessReal or THashKeySymbolLiteral or THashLiteral or THashPattern or + THashSplatExpr or THashSplatNilParameter or THashSplatParameter or THereDoc or + TIdentifierMethodCall or TIfReal or TIfModifierExpr or TInClauseReal or + TInstanceVariableAccessReal or TIntegerLiteralReal or TKeywordParameter or TLEExpr or + TLShiftExprReal or TLTExpr or TLambda or TLeftAssignmentList or TLine or + TLocalVariableAccessReal or TLogicalAndExprReal or TLogicalOrExprReal or TMethod or + TMatchPattern or TModuleDeclaration or TModuloExprReal or TMulExprReal or TNEExpr or + TNextStmt or TNilLiteralReal or TNoRegExpMatchExpr or TNotExprReal or TOptionalParameter or + TPair or TParenthesizedExpr or TParenthesizedPattern or TRShiftExprReal or + TRangeLiteralReal or TRationalLiteral or TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or TRegularArrayLiteral or TRegularMethodCall or TRegularStringLiteral or TRegularSuperCall or TRescueClause or TRescueModifierExpr or TRetryStmt or TReturnStmt or TScopeResolutionConstantAccess or TSelfReal or TSimpleParameterReal or @@ -438,7 +440,7 @@ private module Cached { n = TClassVariableAccessReal(result, _) or n = TComplementExpr(result) or n = TComplexLiteral(result) or - n = TDefinedExpr(result) or + n = TDefinedExprReal(result) or n = TDelimitedSymbolLiteral(result) or n = TDestructuredLeftAssignment(result) or n = TDivExprReal(result) or @@ -495,7 +497,7 @@ private module Cached { n = TNextStmt(result) or n = TNilLiteralReal(result) or n = TNoRegExpMatchExpr(result) or - n = TNotExpr(result) or + n = TNotExprReal(result) or n = TOptionalParameter(result) or n = TPair(result) or n = TParenthesizedExpr(result) or @@ -585,6 +587,8 @@ private module Cached { or result = TConstantWriteAccessSynth(parent, i, _) or + result = TDefinedExprSynth(parent, i) + or result = TDivExprSynth(parent, i) or result = TElseSynth(parent, i) @@ -617,6 +621,8 @@ private module Cached { or result = TNilLiteralSynth(parent, i) or + result = TNotExprSynth(parent, i) + or result = TRangeLiteralSynth(parent, i, _) or result = TRShiftExprSynth(parent, i) @@ -789,10 +795,14 @@ class TNamespace = TClassDeclaration or TModuleDeclaration; class TOperation = TUnaryOperation or TBinaryOperation or TAssignment; +class TDefinedExpr = TDefinedExprReal or TDefinedExprSynth; + class TUnaryOperation = TUnaryLogicalOperation or TUnaryArithmeticOperation or TUnaryBitwiseOperation or TDefinedExpr or TSplatExpr or THashSplatExpr; +class TNotExpr = TNotExprReal or TNotExprSynth; + class TUnaryLogicalOperation = TNotExpr; class TUnaryArithmeticOperation = TUnaryPlusExpr or TUnaryMinusExpr; diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Operation.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Operation.qll index 3f08a8b7869..6fcf0bfc737 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Operation.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Operation.qll @@ -35,6 +35,16 @@ class UnaryOperationGenerated extends UnaryOperationImpl { final override string getOperatorImpl() { result = g.getOperator() } } +abstract class NotExprImpl extends UnaryOperationImpl, TNotExpr { } + +class NotExprReal extends NotExprImpl, UnaryOperationGenerated, TNotExprReal { } + +class NotExprSynth extends NotExprImpl, TNotExprSynth { + final override string getOperatorImpl() { result = "!" } + + final override Expr getOperandImpl() { synthChild(this, 0, result) } +} + class SplatExprReal extends UnaryOperationImpl, TSplatExprReal { private Ruby::SplatArgument g; @@ -67,6 +77,16 @@ class HashSplatExprImpl extends UnaryOperationImpl, THashSplatExpr { final override string getOperatorImpl() { result = "**" } } +abstract class DefinedExprImpl extends UnaryOperationImpl, TDefinedExpr { } + +class DefinedExprReal extends DefinedExprImpl, UnaryOperationGenerated, TDefinedExprReal { } + +class DefinedExprSynth extends DefinedExprImpl, TDefinedExprSynth { + final override string getOperatorImpl() { result = "defined?" } + + final override Expr getOperandImpl() { synthChild(this, 0, result) } +} + abstract class BinaryOperationImpl extends OperationImpl, MethodCallImpl, TBinaryOperation { abstract Stmt getLeftOperandImpl(); diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 47a119ab951..9cd9b561513 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -21,6 +21,7 @@ newtype SynthKind = BraceBlockKind() or CaseMatchKind() or ClassVariableAccessKind(ClassVariable v) or + DefinedExprKind() or DivExprKind() or ElseKind() or ExponentExprKind() or @@ -40,6 +41,7 @@ newtype SynthKind = ModuloExprKind() or MulExprKind() or NilLiteralKind() or + NotExprKind() or RangeLiteralKind(boolean inclusive) { inclusive in [false, true] } or RShiftExprKind() or SimpleParameterKind() or @@ -1258,6 +1260,7 @@ private module HashLiteralDesugar { * ``` * desugars to, roughly, * ```rb + * if not defined? x then x = nil end * xs.each { |__synth__0| x = __synth__0; } * ``` * @@ -1267,53 +1270,137 @@ private module HashLiteralDesugar { * scoped to the synthesized block. */ private module ForLoopDesugar { + private Ruby::AstNode getForLoopPatternChild(Ruby::For for) { + result = for.getPattern() + or + result.getParent() = getForLoopPatternChild(for) + } + + /** Holds if `v` is the `i`th iteration variable of `for`. */ + private predicate forLoopVariable(Ruby::For for, VariableReal v, int i) { + v = + rank[i + 1](VariableReal v0, Ruby::AstNode n, Location l | + n = getForLoopPatternChild(for) and + l = n.getLocation() and + access(n, v0) + | + v0 order by l.getStartLine(), l.getStartColumn() + ) + } + + /** Gets the number of iteration variables of `for`. */ + private int forLoopVariableCount(Ruby::For for) { + result = count(int j | forLoopVariable(for, _, j)) + } + + private Ruby::For toTsFor(ForExpr for) { for = TForExpr(result) } + + /** + * Synthesizes an assignment + * ```rb + * if not defined? v then v = nil end + * ``` + * anchored at index `rootIndex` of `root`. + */ + bindingset[root, rootIndex, v] + private predicate nilAssignUndefined( + AstNode root, int rootIndex, AstNode parent, int i, Child child, VariableReal v + ) { + parent = root and + i = rootIndex and + child = SynthChild(IfKind()) + or + exists(AstNode if_ | if_ = TIfSynth(root, rootIndex) | + parent = if_ and + i = 0 and + child = SynthChild(NotExprKind()) + or + exists(AstNode not_ | not_ = TNotExprSynth(if_, 0) | + parent = not_ and + i = 0 and + child = SynthChild(DefinedExprKind()) + or + parent = TDefinedExprSynth(not_, 0) and + i = 0 and + child = SynthChild(LocalVariableAccessRealKind(v)) + ) + or + parent = if_ and + i = 1 and + child = SynthChild(AssignExprKind()) + or + parent = TAssignExprSynth(if_, 1) and + ( + i = 0 and + child = SynthChild(LocalVariableAccessRealKind(v)) + or + i = 1 and + child = SynthChild(NilLiteralKind()) + ) + ) + } + pragma[nomagic] private predicate forLoopSynthesis(AstNode parent, int i, Child child) { exists(ForExpr for | - // each call parent = for and i = -1 and - child = SynthChild(MethodCallKind("each", false, 0)) + child = SynthChild(StmtSequenceKind()) or - exists(MethodCall eachCall | eachCall = TMethodCallSynth(for, -1, "each", false, 0) | - // receiver - parent = eachCall and - i = 0 and - child = childRef(for.getValue()) // value is the Enumerable + exists(AstNode seq | seq = TStmtSequenceSynth(for, -1) | + exists(VariableReal v, int j | forLoopVariable(toTsFor(for), v, j) | + nilAssignUndefined(seq, j, parent, i, child, v) + ) or - parent = eachCall and - i = 1 and - child = SynthChild(BraceBlockKind()) - or - exists(Block block | block = TBraceBlockSynth(eachCall, 1) | - // block params - parent = block and - i = 0 and - child = SynthChild(SimpleParameterKind()) + exists(int numberOfVars | numberOfVars = forLoopVariableCount(toTsFor(for)) | + // each call + parent = seq and + i = numberOfVars and + child = SynthChild(MethodCallKind("each", false, 0)) or - exists(SimpleParameter param | param = TSimpleParameterSynth(block, 0) | - parent = param and + exists(MethodCall eachCall | + eachCall = TMethodCallSynth(seq, numberOfVars, "each", false, 0) + | + // receiver + parent = eachCall and i = 0 and - child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0))) + child = childRef(for.getValue()) // value is the Enumerable or - // assignment to pattern from for loop to synth parameter - parent = block and + parent = eachCall and i = 1 and - child = SynthChild(AssignExprKind()) + child = SynthChild(BraceBlockKind()) or - parent = TAssignExprSynth(block, 1) and - ( + exists(Block block | block = TBraceBlockSynth(eachCall, 1) | + // block params + parent = block and i = 0 and - child = childRef(for.getPattern()) + child = SynthChild(SimpleParameterKind()) or - i = 1 and - child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0))) + exists(SimpleParameter param | param = TSimpleParameterSynth(block, 0) | + parent = param and + i = 0 and + child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0))) + or + // assignment to pattern from for loop to synth parameter + parent = block and + i = 1 and + child = SynthChild(AssignExprKind()) + or + parent = TAssignExprSynth(block, 1) and + ( + i = 0 and + child = childRef(for.getPattern()) + or + i = 1 and + child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0))) + ) + ) + or + // rest of block body + parent = block and + child = childRef(for.getBody().(Do).getStmt(i - 2)) ) ) - or - // rest of block body - parent = block and - child = childRef(for.getBody().(Do).getStmt(i - 2)) ) ) ) diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index 3625cb83574..5d2a321922f 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -24,29 +24,45 @@ calls/calls.rb: # 67| getAnOperand/getArgument/getRightOperand: [MethodCall] call to bar # 67| getReceiver: [ConstantReadAccess] X # 226| [ForExpr] for ... in ... -# 226| getDesugared: [MethodCall] call to each -# 226| getReceiver: [MethodCall] call to bar -# 226| getReceiver: [SelfVariableAccess] self -# 226| getBlock: [BraceBlock] { ... } -# 226| getParameter: [SimpleParameter] __synth__0__1 -# 226| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 226| getStmt: [AssignExpr] ... = ... +# 226| getDesugared: [StmtSequence] ... +# 226| getStmt: [IfExpr] if ... +# 226| getCondition: [NotExpr] ! ... +# 226| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 226| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] x +# 226| getBranch/getThen: [AssignExpr] ... = ... # 226| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 226| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 227| getStmt: [MethodCall] call to baz -# 227| getReceiver: [SelfVariableAccess] self +# 226| getAnOperand/getRightOperand: [NilLiteral] nil +# 226| getStmt: [MethodCall] call to each +# 226| getReceiver: [MethodCall] call to bar +# 226| getReceiver: [SelfVariableAccess] self +# 226| getBlock: [BraceBlock] { ... } +# 226| getParameter: [SimpleParameter] __synth__0__1 +# 226| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 226| getStmt: [AssignExpr] ... = ... +# 226| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 226| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 227| getStmt: [MethodCall] call to baz +# 227| getReceiver: [SelfVariableAccess] self # 229| [ForExpr] for ... in ... -# 229| getDesugared: [MethodCall] call to each -# 229| getReceiver: [MethodCall] call to bar -# 229| getReceiver: [ConstantReadAccess] X -# 229| getBlock: [BraceBlock] { ... } -# 229| getParameter: [SimpleParameter] __synth__0__1 -# 229| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 229| getStmt: [AssignExpr] ... = ... +# 229| getDesugared: [StmtSequence] ... +# 229| getStmt: [IfExpr] if ... +# 229| getCondition: [NotExpr] ! ... +# 229| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 229| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] x +# 229| getBranch/getThen: [AssignExpr] ... = ... # 229| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 229| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 230| getStmt: [MethodCall] call to baz -# 230| getReceiver: [ConstantReadAccess] X +# 229| getAnOperand/getRightOperand: [NilLiteral] nil +# 229| getStmt: [MethodCall] call to each +# 229| getReceiver: [MethodCall] call to bar +# 229| getReceiver: [ConstantReadAccess] X +# 229| getBlock: [BraceBlock] { ... } +# 229| getParameter: [SimpleParameter] __synth__0__1 +# 229| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 229| getStmt: [AssignExpr] ... = ... +# 229| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 229| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 230| getStmt: [MethodCall] call to baz +# 230| getReceiver: [ConstantReadAccess] X # 249| [HashLiteral] {...} # 249| getDesugared: [MethodCall] call to [] # 249| getReceiver: [ConstantReadAccess] Hash @@ -245,52 +261,74 @@ calls/calls.rb: # 322| getArgument: [LocalVariableAccess] __synth__4 # 322| getStmt: [LocalVariableAccess] __synth__4 # 342| [ForExpr] for ... in ... -# 342| getDesugared: [MethodCall] call to each -# 342| getReceiver: [ArrayLiteral] [...] -# 342| getDesugared: [MethodCall] call to [] -# 342| getReceiver: [ConstantReadAccess] Array -# 342| getArgument: [ArrayLiteral] [...] -# 342| getDesugared: [MethodCall] call to [] -# 342| getReceiver: [ConstantReadAccess] Array -# 342| getArgument: [IntegerLiteral] 1 -# 342| getArgument: [IntegerLiteral] 2 -# 342| getArgument: [IntegerLiteral] 3 -# 342| getArgument: [ArrayLiteral] [...] -# 342| getDesugared: [MethodCall] call to [] -# 342| getReceiver: [ConstantReadAccess] Array -# 342| getArgument: [IntegerLiteral] 4 -# 342| getArgument: [IntegerLiteral] 5 -# 342| getArgument: [IntegerLiteral] 6 -# 342| getBlock: [BraceBlock] { ... } -# 342| getParameter: [SimpleParameter] __synth__0__1 -# 342| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 342| getStmt: [AssignExpr] ... = ... -# 342| getDesugared: [StmtSequence] ... -# 342| getStmt: [AssignExpr] ... = ... -# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3__1 -# 342| getAnOperand/getRightOperand: [SplatExpr] * ... -# 342| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 -# 342| getStmt: [AssignExpr] ... = ... -# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 342| getAnOperand/getRightOperand: [MethodCall] call to [] -# 342| getReceiver: [LocalVariableAccess] __synth__3__1 -# 342| getArgument: [IntegerLiteral] 0 -# 342| getStmt: [AssignExpr] ... = ... -# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] y -# 342| getAnOperand/getRightOperand: [MethodCall] call to [] -# 342| getReceiver: [LocalVariableAccess] __synth__3__1 +# 342| getDesugared: [StmtSequence] ... +# 342| getStmt: [IfExpr] if ... +# 342| getCondition: [NotExpr] ! ... +# 342| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 342| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] x +# 342| getBranch/getThen: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 342| getAnOperand/getRightOperand: [NilLiteral] nil +# 342| getStmt: [IfExpr] if ... +# 342| getCondition: [NotExpr] ! ... +# 342| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 342| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] y +# 342| getBranch/getThen: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] y +# 342| getAnOperand/getRightOperand: [NilLiteral] nil +# 342| getStmt: [IfExpr] if ... +# 342| getCondition: [NotExpr] ! ... +# 342| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 342| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] z +# 342| getBranch/getThen: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] z +# 342| getAnOperand/getRightOperand: [NilLiteral] nil +# 342| getStmt: [MethodCall] call to each +# 342| getReceiver: [ArrayLiteral] [...] +# 342| getDesugared: [MethodCall] call to [] +# 342| getReceiver: [ConstantReadAccess] Array +# 342| getArgument: [ArrayLiteral] [...] +# 342| getDesugared: [MethodCall] call to [] +# 342| getReceiver: [ConstantReadAccess] Array # 342| getArgument: [IntegerLiteral] 1 -# 342| getStmt: [AssignExpr] ... = ... -# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] z -# 342| getAnOperand/getRightOperand: [MethodCall] call to [] -# 342| getReceiver: [LocalVariableAccess] __synth__3__1 # 342| getArgument: [IntegerLiteral] 2 -# 342| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) -# 343| getStmt: [MethodCall] call to foo -# 343| getReceiver: [SelfVariableAccess] self -# 343| getArgument: [LocalVariableAccess] x -# 343| getArgument: [LocalVariableAccess] y -# 343| getArgument: [LocalVariableAccess] z +# 342| getArgument: [IntegerLiteral] 3 +# 342| getArgument: [ArrayLiteral] [...] +# 342| getDesugared: [MethodCall] call to [] +# 342| getReceiver: [ConstantReadAccess] Array +# 342| getArgument: [IntegerLiteral] 4 +# 342| getArgument: [IntegerLiteral] 5 +# 342| getArgument: [IntegerLiteral] 6 +# 342| getBlock: [BraceBlock] { ... } +# 342| getParameter: [SimpleParameter] __synth__0__1 +# 342| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 342| getStmt: [AssignExpr] ... = ... +# 342| getDesugared: [StmtSequence] ... +# 342| getStmt: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3__1 +# 342| getAnOperand/getRightOperand: [SplatExpr] * ... +# 342| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 +# 342| getStmt: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 342| getAnOperand/getRightOperand: [MethodCall] call to [] +# 342| getReceiver: [LocalVariableAccess] __synth__3__1 +# 342| getArgument: [IntegerLiteral] 0 +# 342| getStmt: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] y +# 342| getAnOperand/getRightOperand: [MethodCall] call to [] +# 342| getReceiver: [LocalVariableAccess] __synth__3__1 +# 342| getArgument: [IntegerLiteral] 1 +# 342| getStmt: [AssignExpr] ... = ... +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] z +# 342| getAnOperand/getRightOperand: [MethodCall] call to [] +# 342| getReceiver: [LocalVariableAccess] __synth__3__1 +# 342| getArgument: [IntegerLiteral] 2 +# 342| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 343| getStmt: [MethodCall] call to foo +# 343| getReceiver: [SelfVariableAccess] self +# 343| getArgument: [LocalVariableAccess] x +# 343| getArgument: [LocalVariableAccess] y +# 343| getArgument: [LocalVariableAccess] z # 364| [MethodCall] call to empty? # 364| getDesugared: [StmtSequence] ... # 364| getStmt: [AssignExpr] ... = ... @@ -594,139 +632,185 @@ literals/literals.rb: # 199| getValue: [ConstantReadAccess] Z control/loops.rb: # 9| [ForExpr] for ... in ... -# 9| getDesugared: [MethodCall] call to each -# 9| getReceiver: [RangeLiteral] _ .. _ -# 9| getBegin: [IntegerLiteral] 1 -# 9| getEnd: [IntegerLiteral] 10 -# 9| getBlock: [BraceBlock] { ... } -# 9| getParameter: [SimpleParameter] __synth__0__1 -# 9| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 9| getStmt: [AssignExpr] ... = ... +# 9| getDesugared: [StmtSequence] ... +# 9| getStmt: [IfExpr] if ... +# 9| getCondition: [NotExpr] ! ... +# 9| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 9| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] n +# 9| getBranch/getThen: [AssignExpr] ... = ... # 9| getAnOperand/getLeftOperand: [LocalVariableAccess] n -# 9| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 10| getStmt: [AssignAddExpr] ... += ... -# 10| getDesugared: [AssignExpr] ... = ... -# 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 10| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 10| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 10| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n -# 11| getStmt: [AssignExpr] ... = ... -# 11| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 11| getAnOperand/getRightOperand: [LocalVariableAccess] n +# 9| getAnOperand/getRightOperand: [NilLiteral] nil +# 9| getStmt: [MethodCall] call to each +# 9| getReceiver: [RangeLiteral] _ .. _ +# 9| getBegin: [IntegerLiteral] 1 +# 9| getEnd: [IntegerLiteral] 10 +# 9| getBlock: [BraceBlock] { ... } +# 9| getParameter: [SimpleParameter] __synth__0__1 +# 9| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 9| getStmt: [AssignExpr] ... = ... +# 9| getAnOperand/getLeftOperand: [LocalVariableAccess] n +# 9| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 10| getStmt: [AssignAddExpr] ... += ... +# 10| getDesugared: [AssignExpr] ... = ... +# 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 10| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 10| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 10| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n +# 11| getStmt: [AssignExpr] ... = ... +# 11| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 11| getAnOperand/getRightOperand: [LocalVariableAccess] n # 16| [ForExpr] for ... in ... -# 16| getDesugared: [MethodCall] call to each -# 16| getReceiver: [RangeLiteral] _ .. _ -# 16| getBegin: [IntegerLiteral] 1 -# 16| getEnd: [IntegerLiteral] 10 -# 16| getBlock: [BraceBlock] { ... } -# 16| getParameter: [SimpleParameter] __synth__0__1 -# 16| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 16| getStmt: [AssignExpr] ... = ... +# 16| getDesugared: [StmtSequence] ... +# 16| getStmt: [IfExpr] if ... +# 16| getCondition: [NotExpr] ! ... +# 16| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 16| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] n +# 16| getBranch/getThen: [AssignExpr] ... = ... # 16| getAnOperand/getLeftOperand: [LocalVariableAccess] n -# 16| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 17| getStmt: [AssignAddExpr] ... += ... -# 17| getDesugared: [AssignExpr] ... = ... -# 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 17| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 17| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 17| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n -# 18| getStmt: [AssignSubExpr] ... -= ... -# 18| getDesugared: [AssignExpr] ... = ... -# 18| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 18| getAnOperand/getRightOperand: [SubExpr] ... - ... -# 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 18| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n +# 16| getAnOperand/getRightOperand: [NilLiteral] nil +# 16| getStmt: [MethodCall] call to each +# 16| getReceiver: [RangeLiteral] _ .. _ +# 16| getBegin: [IntegerLiteral] 1 +# 16| getEnd: [IntegerLiteral] 10 +# 16| getBlock: [BraceBlock] { ... } +# 16| getParameter: [SimpleParameter] __synth__0__1 +# 16| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 16| getStmt: [AssignExpr] ... = ... +# 16| getAnOperand/getLeftOperand: [LocalVariableAccess] n +# 16| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 17| getStmt: [AssignAddExpr] ... += ... +# 17| getDesugared: [AssignExpr] ... = ... +# 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 17| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 17| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 17| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n +# 18| getStmt: [AssignSubExpr] ... -= ... +# 18| getDesugared: [AssignExpr] ... = ... +# 18| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 18| getAnOperand/getRightOperand: [SubExpr] ... - ... +# 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 18| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n # 22| [ForExpr] for ... in ... -# 22| getDesugared: [MethodCall] call to each -# 22| getReceiver: [HashLiteral] {...} -# 22| getDesugared: [MethodCall] call to [] -# 22| getReceiver: [ConstantReadAccess] Hash -# 22| getArgument: [Pair] Pair -# 22| getKey: [SymbolLiteral] :foo -# 22| getComponent: [StringTextComponent] foo -# 22| getValue: [IntegerLiteral] 0 -# 22| getArgument: [Pair] Pair -# 22| getKey: [SymbolLiteral] :bar -# 22| getComponent: [StringTextComponent] bar -# 22| getValue: [IntegerLiteral] 1 -# 22| getBlock: [BraceBlock] { ... } -# 22| getParameter: [SimpleParameter] __synth__0__1 -# 22| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 22| getStmt: [AssignExpr] ... = ... -# 22| getDesugared: [StmtSequence] ... -# 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 -# 22| getAnOperand/getRightOperand: [SplatExpr] * ... -# 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 -# 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] key -# 22| getAnOperand/getRightOperand: [MethodCall] call to [] -# 22| getReceiver: [LocalVariableAccess] __synth__2__1 -# 22| getArgument: [IntegerLiteral] 0 -# 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] value -# 22| getAnOperand/getRightOperand: [MethodCall] call to [] -# 22| getReceiver: [LocalVariableAccess] __synth__2__1 -# 22| getArgument: [IntegerLiteral] 1 -# 22| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) -# 23| getStmt: [AssignAddExpr] ... += ... -# 23| getDesugared: [AssignExpr] ... = ... -# 23| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 23| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 23| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 23| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 24| getStmt: [AssignMulExpr] ... *= ... -# 24| getDesugared: [AssignExpr] ... = ... -# 24| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 24| getAnOperand/getRightOperand: [MulExpr] ... * ... -# 24| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 24| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 22| getDesugared: [StmtSequence] ... +# 22| getStmt: [IfExpr] if ... +# 22| getCondition: [NotExpr] ! ... +# 22| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] key +# 22| getBranch/getThen: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] key +# 22| getAnOperand/getRightOperand: [NilLiteral] nil +# 22| getStmt: [IfExpr] if ... +# 22| getCondition: [NotExpr] ! ... +# 22| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] value +# 22| getBranch/getThen: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] value +# 22| getAnOperand/getRightOperand: [NilLiteral] nil +# 22| getStmt: [MethodCall] call to each +# 22| getReceiver: [HashLiteral] {...} +# 22| getDesugared: [MethodCall] call to [] +# 22| getReceiver: [ConstantReadAccess] Hash +# 22| getArgument: [Pair] Pair +# 22| getKey: [SymbolLiteral] :foo +# 22| getComponent: [StringTextComponent] foo +# 22| getValue: [IntegerLiteral] 0 +# 22| getArgument: [Pair] Pair +# 22| getKey: [SymbolLiteral] :bar +# 22| getComponent: [StringTextComponent] bar +# 22| getValue: [IntegerLiteral] 1 +# 22| getBlock: [BraceBlock] { ... } +# 22| getParameter: [SimpleParameter] __synth__0__1 +# 22| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 22| getStmt: [AssignExpr] ... = ... +# 22| getDesugared: [StmtSequence] ... +# 22| getStmt: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 +# 22| getAnOperand/getRightOperand: [SplatExpr] * ... +# 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 +# 22| getStmt: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] key +# 22| getAnOperand/getRightOperand: [MethodCall] call to [] +# 22| getReceiver: [LocalVariableAccess] __synth__2__1 +# 22| getArgument: [IntegerLiteral] 0 +# 22| getStmt: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] value +# 22| getAnOperand/getRightOperand: [MethodCall] call to [] +# 22| getReceiver: [LocalVariableAccess] __synth__2__1 +# 22| getArgument: [IntegerLiteral] 1 +# 22| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 23| getStmt: [AssignAddExpr] ... += ... +# 23| getDesugared: [AssignExpr] ... = ... +# 23| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 23| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 23| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 23| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 24| getStmt: [AssignMulExpr] ... *= ... +# 24| getDesugared: [AssignExpr] ... = ... +# 24| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 24| getAnOperand/getRightOperand: [MulExpr] ... * ... +# 24| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 24| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value # 28| [ForExpr] for ... in ... -# 28| getDesugared: [MethodCall] call to each -# 28| getReceiver: [HashLiteral] {...} -# 28| getDesugared: [MethodCall] call to [] -# 28| getReceiver: [ConstantReadAccess] Hash -# 28| getArgument: [Pair] Pair -# 28| getKey: [SymbolLiteral] :foo -# 28| getComponent: [StringTextComponent] foo -# 28| getValue: [IntegerLiteral] 0 -# 28| getArgument: [Pair] Pair -# 28| getKey: [SymbolLiteral] :bar -# 28| getComponent: [StringTextComponent] bar -# 28| getValue: [IntegerLiteral] 1 -# 28| getBlock: [BraceBlock] { ... } -# 28| getParameter: [SimpleParameter] __synth__0__1 -# 28| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 28| getStmt: [AssignExpr] ... = ... -# 28| getDesugared: [StmtSequence] ... -# 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 -# 28| getAnOperand/getRightOperand: [SplatExpr] * ... -# 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 -# 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] key -# 28| getAnOperand/getRightOperand: [MethodCall] call to [] -# 28| getReceiver: [LocalVariableAccess] __synth__2__1 -# 28| getArgument: [IntegerLiteral] 0 -# 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] value -# 28| getAnOperand/getRightOperand: [MethodCall] call to [] -# 28| getReceiver: [LocalVariableAccess] __synth__2__1 -# 28| getArgument: [IntegerLiteral] 1 -# 28| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) -# 29| getStmt: [AssignAddExpr] ... += ... -# 29| getDesugared: [AssignExpr] ... = ... -# 29| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 29| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 29| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 29| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 30| getStmt: [AssignDivExpr] ... /= ... -# 30| getDesugared: [AssignExpr] ... = ... -# 30| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 30| getAnOperand/getRightOperand: [DivExpr] ... / ... -# 30| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 30| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 31| getStmt: [BreakStmt] break +# 28| getDesugared: [StmtSequence] ... +# 28| getStmt: [IfExpr] if ... +# 28| getCondition: [NotExpr] ! ... +# 28| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] key +# 28| getBranch/getThen: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] key +# 28| getAnOperand/getRightOperand: [NilLiteral] nil +# 28| getStmt: [IfExpr] if ... +# 28| getCondition: [NotExpr] ! ... +# 28| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] value +# 28| getBranch/getThen: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] value +# 28| getAnOperand/getRightOperand: [NilLiteral] nil +# 28| getStmt: [MethodCall] call to each +# 28| getReceiver: [HashLiteral] {...} +# 28| getDesugared: [MethodCall] call to [] +# 28| getReceiver: [ConstantReadAccess] Hash +# 28| getArgument: [Pair] Pair +# 28| getKey: [SymbolLiteral] :foo +# 28| getComponent: [StringTextComponent] foo +# 28| getValue: [IntegerLiteral] 0 +# 28| getArgument: [Pair] Pair +# 28| getKey: [SymbolLiteral] :bar +# 28| getComponent: [StringTextComponent] bar +# 28| getValue: [IntegerLiteral] 1 +# 28| getBlock: [BraceBlock] { ... } +# 28| getParameter: [SimpleParameter] __synth__0__1 +# 28| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 28| getStmt: [AssignExpr] ... = ... +# 28| getDesugared: [StmtSequence] ... +# 28| getStmt: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 +# 28| getAnOperand/getRightOperand: [SplatExpr] * ... +# 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 +# 28| getStmt: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] key +# 28| getAnOperand/getRightOperand: [MethodCall] call to [] +# 28| getReceiver: [LocalVariableAccess] __synth__2__1 +# 28| getArgument: [IntegerLiteral] 0 +# 28| getStmt: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] value +# 28| getAnOperand/getRightOperand: [MethodCall] call to [] +# 28| getReceiver: [LocalVariableAccess] __synth__2__1 +# 28| getArgument: [IntegerLiteral] 1 +# 28| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 29| getStmt: [AssignAddExpr] ... += ... +# 29| getDesugared: [AssignExpr] ... = ... +# 29| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 29| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 29| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 29| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 30| getStmt: [AssignDivExpr] ... /= ... +# 30| getDesugared: [AssignExpr] ... = ... +# 30| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 30| getAnOperand/getRightOperand: [DivExpr] ... / ... +# 30| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 30| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 31| getStmt: [BreakStmt] break # 36| [AssignAddExpr] ... += ... # 36| getDesugared: [AssignExpr] ... = ... # 36| getAnOperand/getLeftOperand: [LocalVariableAccess] x @@ -985,29 +1069,37 @@ params/params.rb: # 21| getReceiver: [ConstantReadAccess] Array erb/template.html.erb: # 27| [ForExpr] for ... in ... -# 27| getDesugared: [MethodCall] call to each -# 27| getReceiver: [ArrayLiteral] [...] -# 27| getDesugared: [MethodCall] call to [] -# 27| getReceiver: [ConstantReadAccess] Array -# 27| getArgument: [StringLiteral] "foo" -# 27| getComponent: [StringTextComponent] foo -# 27| getArgument: [StringLiteral] "bar" -# 27| getComponent: [StringTextComponent] bar -# 27| getArgument: [StringLiteral] "baz" -# 27| getComponent: [StringTextComponent] baz -# 27| getBlock: [BraceBlock] { ... } -# 27| getParameter: [SimpleParameter] __synth__0__1 -# 27| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 27| getStmt: [AssignExpr] ... = ... +# 27| getDesugared: [StmtSequence] ... +# 27| getStmt: [IfExpr] if ... +# 27| getCondition: [NotExpr] ! ... +# 27| getAnOperand/getOperand/getReceiver: [DefinedExpr] defined? ... +# 27| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] x +# 27| getBranch/getThen: [AssignExpr] ... = ... # 27| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 27| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 28| getStmt: [AssignAddExpr] ... += ... -# 28| getDesugared: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs -# 28| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 28| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xs -# 28| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] x -# 29| getStmt: [LocalVariableAccess] xs +# 27| getAnOperand/getRightOperand: [NilLiteral] nil +# 27| getStmt: [MethodCall] call to each +# 27| getReceiver: [ArrayLiteral] [...] +# 27| getDesugared: [MethodCall] call to [] +# 27| getReceiver: [ConstantReadAccess] Array +# 27| getArgument: [StringLiteral] "foo" +# 27| getComponent: [StringTextComponent] foo +# 27| getArgument: [StringLiteral] "bar" +# 27| getComponent: [StringTextComponent] bar +# 27| getArgument: [StringLiteral] "baz" +# 27| getComponent: [StringTextComponent] baz +# 27| getBlock: [BraceBlock] { ... } +# 27| getParameter: [SimpleParameter] __synth__0__1 +# 27| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 27| getStmt: [AssignExpr] ... = ... +# 27| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 27| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 28| getStmt: [AssignAddExpr] ... += ... +# 28| getDesugared: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs +# 28| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 28| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xs +# 28| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] x +# 29| getStmt: [LocalVariableAccess] xs gems/test.gemspec: # 2| [AssignExpr] ... = ... # 2| getDesugared: [StmtSequence] ... diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index 612b58e41e3..0c0a78423cf 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -10,6 +10,8 @@ exprValue | calls/calls.rb:26:7:26:7 | 1 | 1 | int | | calls/calls.rb:36:9:36:11 | 100 | 100 | int | | calls/calls.rb:36:14:36:16 | 200 | 200 | int | +| calls/calls.rb:226:1:228:3 | nil | nil | nil | +| calls/calls.rb:229:1:231:3 | nil | nil | nil | | calls/calls.rb:280:5:280:8 | :blah | :blah | symbol | | calls/calls.rb:281:5:281:8 | :blah | :blah | symbol | | calls/calls.rb:290:11:290:16 | "blah" | blah | string | @@ -57,6 +59,9 @@ exprValue | calls/calls.rb:322:31:322:31 | 1 | 1 | int | | calls/calls.rb:322:37:322:37 | 2 | 2 | int | | calls/calls.rb:330:31:330:37 | "error" | error | string | +| calls/calls.rb:342:1:344:3 | nil | nil | nil | +| calls/calls.rb:342:1:344:3 | nil | nil | nil | +| calls/calls.rb:342:1:344:3 | nil | nil | nil | | calls/calls.rb:342:5:342:5 | 0 | 0 | int | | calls/calls.rb:342:8:342:8 | 1 | 1 | int | | calls/calls.rb:342:11:342:11 | 2 | 2 | int | @@ -330,16 +335,22 @@ exprValue | control/loops.rb:4:5:4:5 | 0 | 0 | int | | control/loops.rb:5:5:5:5 | 0 | 0 | int | | control/loops.rb:6:5:6:5 | 0 | 0 | int | +| control/loops.rb:9:1:12:3 | nil | nil | nil | | control/loops.rb:9:10:9:10 | 1 | 1 | int | | control/loops.rb:9:13:9:14 | 10 | 10 | int | +| control/loops.rb:16:1:19:3 | nil | nil | nil | | control/loops.rb:16:10:16:10 | 1 | 1 | int | | control/loops.rb:16:13:16:14 | 10 | 10 | int | +| control/loops.rb:22:1:25:3 | nil | nil | nil | +| control/loops.rb:22:1:25:3 | nil | nil | nil | | control/loops.rb:22:5:22:7 | 0 | 0 | int | | control/loops.rb:22:10:22:14 | 1 | 1 | int | | control/loops.rb:22:20:22:22 | :foo | :foo | symbol | | control/loops.rb:22:25:22:25 | 0 | 0 | int | | control/loops.rb:22:28:22:30 | :bar | :bar | symbol | | control/loops.rb:22:33:22:33 | 1 | 1 | int | +| control/loops.rb:28:1:32:3 | nil | nil | nil | +| control/loops.rb:28:1:32:3 | nil | nil | nil | | control/loops.rb:28:6:28:8 | 0 | 0 | int | | control/loops.rb:28:11:28:15 | 1 | 1 | int | | control/loops.rb:28:22:28:24 | :foo | :foo | symbol | @@ -365,6 +376,7 @@ exprValue | control/loops.rb:66:11:66:11 | y | 0 | int | | erb/template.html.erb:19:5:19:17 | "hello world" | hello world | string | | erb/template.html.erb:25:9:25:10 | "" | | string | +| erb/template.html.erb:27:6:31:8 | nil | nil | nil | | erb/template.html.erb:27:16:27:20 | "foo" | foo | string | | erb/template.html.erb:27:23:27:27 | "bar" | bar | string | | erb/template.html.erb:27:30:27:34 | "baz" | baz | string | @@ -934,6 +946,8 @@ exprCfgNodeValue | calls/calls.rb:26:7:26:7 | 1 | 1 | int | | calls/calls.rb:36:9:36:11 | 100 | 100 | int | | calls/calls.rb:36:14:36:16 | 200 | 200 | int | +| calls/calls.rb:226:1:228:3 | nil | nil | nil | +| calls/calls.rb:229:1:231:3 | nil | nil | nil | | calls/calls.rb:280:5:280:8 | :blah | :blah | symbol | | calls/calls.rb:281:5:281:8 | :blah | :blah | symbol | | calls/calls.rb:290:11:290:16 | "blah" | blah | string | @@ -981,6 +995,9 @@ exprCfgNodeValue | calls/calls.rb:322:31:322:31 | 1 | 1 | int | | calls/calls.rb:322:37:322:37 | 2 | 2 | int | | calls/calls.rb:330:31:330:37 | "error" | error | string | +| calls/calls.rb:342:1:344:3 | nil | nil | nil | +| calls/calls.rb:342:1:344:3 | nil | nil | nil | +| calls/calls.rb:342:1:344:3 | nil | nil | nil | | calls/calls.rb:342:5:342:5 | 0 | 0 | int | | calls/calls.rb:342:8:342:8 | 1 | 1 | int | | calls/calls.rb:342:11:342:11 | 2 | 2 | int | @@ -1226,16 +1243,22 @@ exprCfgNodeValue | control/loops.rb:4:5:4:5 | 0 | 0 | int | | control/loops.rb:5:5:5:5 | 0 | 0 | int | | control/loops.rb:6:5:6:5 | 0 | 0 | int | +| control/loops.rb:9:1:12:3 | nil | nil | nil | | control/loops.rb:9:10:9:10 | 1 | 1 | int | | control/loops.rb:9:13:9:14 | 10 | 10 | int | +| control/loops.rb:16:1:19:3 | nil | nil | nil | | control/loops.rb:16:10:16:10 | 1 | 1 | int | | control/loops.rb:16:13:16:14 | 10 | 10 | int | +| control/loops.rb:22:1:25:3 | nil | nil | nil | +| control/loops.rb:22:1:25:3 | nil | nil | nil | | control/loops.rb:22:5:22:7 | 0 | 0 | int | | control/loops.rb:22:10:22:14 | 1 | 1 | int | | control/loops.rb:22:20:22:22 | :foo | :foo | symbol | | control/loops.rb:22:25:22:25 | 0 | 0 | int | | control/loops.rb:22:28:22:30 | :bar | :bar | symbol | | control/loops.rb:22:33:22:33 | 1 | 1 | int | +| control/loops.rb:28:1:32:3 | nil | nil | nil | +| control/loops.rb:28:1:32:3 | nil | nil | nil | | control/loops.rb:28:6:28:8 | 0 | 0 | int | | control/loops.rb:28:11:28:15 | 1 | 1 | int | | control/loops.rb:28:22:28:24 | :foo | :foo | symbol | @@ -1261,6 +1284,7 @@ exprCfgNodeValue | control/loops.rb:66:11:66:11 | y | 0 | int | | erb/template.html.erb:19:5:19:17 | "hello world" | hello world | string | | erb/template.html.erb:25:9:25:10 | "" | | string | +| erb/template.html.erb:27:6:31:8 | nil | nil | nil | | erb/template.html.erb:27:16:27:20 | "foo" | foo | string | | erb/template.html.erb:27:23:27:27 | "bar" | bar | string | | erb/template.html.erb:27:30:27:34 | "baz" | baz | string | diff --git a/ruby/ql/test/library-tests/ast/calls/calls.expected b/ruby/ql/test/library-tests/ast/calls/calls.expected index 628b3578994..ff8ef702c34 100644 --- a/ruby/ql/test/library-tests/ast/calls/calls.expected +++ b/ruby/ql/test/library-tests/ast/calls/calls.expected @@ -250,10 +250,14 @@ callsWithReceiver | calls.rb:222:11:222:13 | call to foo | calls.rb:222:11:222:13 | self | | calls.rb:223:1:223:6 | call to bar | calls.rb:223:1:223:1 | X | | calls.rb:223:14:223:19 | call to foo | calls.rb:223:14:223:14 | X | +| calls.rb:226:1:228:3 | ! ... | calls.rb:226:1:228:3 | defined? ... | | calls.rb:226:1:228:3 | call to each | calls.rb:226:10:226:12 | call to bar | +| calls.rb:226:1:228:3 | defined? ... | calls.rb:226:1:228:3 | x | | calls.rb:226:10:226:12 | call to bar | calls.rb:226:10:226:12 | self | | calls.rb:227:3:227:5 | call to baz | calls.rb:227:3:227:5 | self | +| calls.rb:229:1:231:3 | ! ... | calls.rb:229:1:231:3 | defined? ... | | calls.rb:229:1:231:3 | call to each | calls.rb:229:10:229:15 | call to bar | +| calls.rb:229:1:231:3 | defined? ... | calls.rb:229:1:231:3 | x | | calls.rb:229:10:229:15 | call to bar | calls.rb:229:10:229:10 | X | | calls.rb:230:3:230:8 | call to baz | calls.rb:230:3:230:3 | X | | calls.rb:234:1:234:3 | call to foo | calls.rb:234:1:234:3 | self | @@ -374,8 +378,14 @@ callsWithReceiver | calls.rb:330:13:330:15 | call to bar | calls.rb:330:13:330:15 | self | | calls.rb:330:25:330:37 | call to print | calls.rb:330:25:330:37 | self | | calls.rb:338:3:338:13 | call to bar | calls.rb:338:3:338:13 | self | +| calls.rb:342:1:344:3 | ! ... | calls.rb:342:1:344:3 | defined? ... | +| calls.rb:342:1:344:3 | ! ... | calls.rb:342:1:344:3 | defined? ... | +| calls.rb:342:1:344:3 | ! ... | calls.rb:342:1:344:3 | defined? ... | | calls.rb:342:1:344:3 | * ... | calls.rb:342:1:344:3 | __synth__0__1 | | calls.rb:342:1:344:3 | call to each | calls.rb:342:16:342:33 | [...] | +| calls.rb:342:1:344:3 | defined? ... | calls.rb:342:1:344:3 | x | +| calls.rb:342:1:344:3 | defined? ... | calls.rb:342:1:344:3 | y | +| calls.rb:342:1:344:3 | defined? ... | calls.rb:342:1:344:3 | z | | calls.rb:342:5:342:5 | call to [] | calls.rb:342:5:342:5 | __synth__3__1 | | calls.rb:342:8:342:8 | call to [] | calls.rb:342:8:342:8 | __synth__3__1 | | calls.rb:342:11:342:11 | call to [] | calls.rb:342:11:342:11 | __synth__3__1 | diff --git a/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected b/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected index 3d78655dbbb..67cee0cd160 100644 --- a/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected +++ b/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected @@ -22,6 +22,12 @@ conditionalExprs | conditionals.rb:61:1:64:3 | if ... | IfExpr | conditionals.rb:61:4:61:8 | ... > ... | conditionals.rb:63:1:63:4 | else ... | false | | conditionals.rb:67:1:70:3 | if ... | IfExpr | conditionals.rb:67:4:67:8 | ... > ... | conditionals.rb:67:10:67:13 | then ... | true | | conditionals.rb:67:1:70:3 | if ... | IfExpr | conditionals.rb:67:4:67:8 | ... > ... | conditionals.rb:68:1:69:5 | else ... | false | +| loops.rb:9:1:12:3 | if ... | IfExpr | loops.rb:9:1:12:3 | ! ... | loops.rb:9:1:12:3 | ... = ... | true | +| loops.rb:16:1:19:3 | if ... | IfExpr | loops.rb:16:1:19:3 | ! ... | loops.rb:16:1:19:3 | ... = ... | true | +| loops.rb:22:1:25:3 | if ... | IfExpr | loops.rb:22:1:25:3 | ! ... | loops.rb:22:1:25:3 | ... = ... | true | +| loops.rb:22:1:25:3 | if ... | IfExpr | loops.rb:22:1:25:3 | ! ... | loops.rb:22:1:25:3 | ... = ... | true | +| loops.rb:28:1:32:3 | if ... | IfExpr | loops.rb:28:1:32:3 | ! ... | loops.rb:28:1:32:3 | ... = ... | true | +| loops.rb:28:1:32:3 | if ... | IfExpr | loops.rb:28:1:32:3 | ! ... | loops.rb:28:1:32:3 | ... = ... | true | ifExprs | conditionals.rb:10:1:12:3 | if ... | IfExpr | conditionals.rb:10:4:10:8 | ... > ... | conditionals.rb:10:10:11:5 | then ... | (none) | false | | conditionals.rb:15:1:19:3 | if ... | IfExpr | conditionals.rb:15:4:15:9 | ... == ... | conditionals.rb:15:10:16:5 | then ... | else ... | false | diff --git a/ruby/ql/test/library-tests/ast/control/ControlExpr.expected b/ruby/ql/test/library-tests/ast/control/ControlExpr.expected index 933b4561162..58e30085922 100644 --- a/ruby/ql/test/library-tests/ast/control/ControlExpr.expected +++ b/ruby/ql/test/library-tests/ast/control/ControlExpr.expected @@ -27,9 +27,15 @@ | conditionals.rb:61:1:64:3 | if ... | IfExpr | | conditionals.rb:67:1:70:3 | if ... | IfExpr | | loops.rb:9:1:12:3 | for ... in ... | ForExpr | +| loops.rb:9:1:12:3 | if ... | IfExpr | | loops.rb:16:1:19:3 | for ... in ... | ForExpr | +| loops.rb:16:1:19:3 | if ... | IfExpr | | loops.rb:22:1:25:3 | for ... in ... | ForExpr | +| loops.rb:22:1:25:3 | if ... | IfExpr | +| loops.rb:22:1:25:3 | if ... | IfExpr | | loops.rb:28:1:32:3 | for ... in ... | ForExpr | +| loops.rb:28:1:32:3 | if ... | IfExpr | +| loops.rb:28:1:32:3 | if ... | IfExpr | | loops.rb:35:1:39:3 | while ... | WhileExpr | | loops.rb:42:1:45:3 | while ... | WhileExpr | | loops.rb:48:1:48:19 | ... while ... | WhileModifierExpr | diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index 071f118db84..e3b0e01adfe 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -2377,7 +2377,7 @@ cfg.rb: #-----| -> \u1234 # 88| ... = ... -#-----| -> Array +#-----| -> x # 88| "\u1234#{...}\n" #-----| -> ... = ... @@ -2394,9 +2394,21 @@ cfg.rb: # 88| \n #-----| -> "\u1234#{...}\n" +# 90| ... +#-----| -> $global + +# 90| ... = ... +#-----| -> if ... + # 90| ... = ... #-----| -> x +# 90| [false] ! ... +#-----| false -> if ... + +# 90| [true] ! ... +#-----| true -> x + # 90| __synth__0__1 #-----| -> x @@ -2404,7 +2416,11 @@ cfg.rb: #-----| -> ... = ... # 90| call to each -#-----| -> $global +#-----| -> ... + +# 90| defined? ... +#-----| false -> [true] ! ... +#-----| true -> [false] ! ... # 90| enter { ... } #-----| -> __synth__0__1 @@ -2414,6 +2430,18 @@ cfg.rb: # 90| exit { ... } (normal) #-----| -> exit { ... } +# 90| if ... +#-----| -> Array + +# 90| nil +#-----| -> ... = ... + +# 90| x +#-----| -> nil + +# 90| x +#-----| -> defined? ... + # 90| { ... } #-----| -> call to each diff --git a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected index 0e39e2924bd..42b7ed153d3 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -25,7 +25,10 @@ callsWithNoArguments | cfg.rb:60:17:60:17 | call to b | | cfg.rb:62:7:62:12 | * ... | | cfg.rb:62:17:62:27 | * ... | +| cfg.rb:90:1:93:3 | [false] ! ... | +| cfg.rb:90:1:93:3 | [true] ! ... | | cfg.rb:90:1:93:3 | call to each | +| cfg.rb:90:1:93:3 | defined? ... | | cfg.rb:98:10:98:15 | ** ... | | cfg.rb:98:30:98:35 | ** ... | | cfg.rb:138:17:138:23 | * ... | diff --git a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected index 60f62362f75..064e9a5482e 100644 --- a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected @@ -2399,6 +2399,7 @@ | UseUseExplosion.rb:24:5:25:7 | use | UseUseExplosion.rb:1:1:26:3 | C | | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | +| local_dataflow.rb:1:1:150:3 | | local_dataflow.rb:10:5:13:3 | x | | local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a | @@ -2424,28 +2425,45 @@ | local_dataflow.rb:9:1:9:5 | array | local_dataflow.rb:10:14:10:18 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | +| local_dataflow.rb:10:5:13:3 | ... | local_dataflow.rb:10:1:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:10:5:13:3 | if ... | | local_dataflow.rb:10:5:13:3 | self | local_dataflow.rb:11:1:11:2 | self | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:15:1:17:3 | x | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x | -| local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:1:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:5:13:3 | ... | +| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | x | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | phi | | local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:14:10:18 | [post] array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:11:1:11:2 | [post] self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:12:3:12:5 | self | +| local_dataflow.rb:15:1:17:3 | ... = ... | local_dataflow.rb:15:1:17:3 | if ... | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:19:1:21:3 | x | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x | +| local_dataflow.rb:15:1:17:3 | call to each | local_dataflow.rb:15:1:17:3 | ... | +| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | ... = ... | +| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | x | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | phi | | local_dataflow.rb:15:10:15:14 | [post] array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:16:9:16:10 | 10 | local_dataflow.rb:16:3:16:10 | break | +| local_dataflow.rb:19:1:21:3 | ... = ... | local_dataflow.rb:19:1:21:3 | if ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x | +| local_dataflow.rb:19:1:21:3 | call to each | local_dataflow.rb:19:1:21:3 | ... | +| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | ... = ... | +| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | x | +| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | phi | | local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:20:6:20:6 | x | | local_dataflow.rb:24:2:24:8 | break | local_dataflow.rb:23:1:25:3 | while ... | | local_dataflow.rb:24:8:24:8 | 5 | local_dataflow.rb:24:2:24:8 | break | diff --git a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected index 2ac17e470d7..b6808099a0b 100644 --- a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected +++ b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected @@ -831,13 +831,22 @@ arg | local_dataflow.rb:9:10:9:10 | 1 | local_dataflow.rb:9:9:9:15 | call to [] | position 0 | | local_dataflow.rb:9:12:9:12 | 2 | local_dataflow.rb:9:9:9:15 | call to [] | position 1 | | local_dataflow.rb:9:14:9:14 | 3 | local_dataflow.rb:9:9:9:15 | call to [] | position 2 | +| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [false] ! ... | self | +| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [true] ! ... | self | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | defined? ... | self | | local_dataflow.rb:10:5:13:3 | { ... } | local_dataflow.rb:10:5:13:3 | call to each | block | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:10:5:13:3 | call to each | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:11:1:11:2 | call to do | self | | local_dataflow.rb:12:3:12:5 | self | local_dataflow.rb:12:3:12:5 | call to p | self | | local_dataflow.rb:12:5:12:5 | x | local_dataflow.rb:12:3:12:5 | call to p | position 0 | +| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [false] ! ... | self | +| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [true] ! ... | self | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | defined? ... | self | | local_dataflow.rb:15:1:17:3 | { ... } | local_dataflow.rb:15:1:17:3 | call to each | block | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:15:1:17:3 | call to each | self | +| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [false] ! ... | self | +| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [true] ! ... | self | +| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | defined? ... | self | | local_dataflow.rb:19:1:21:3 | { ... } | local_dataflow.rb:19:1:21:3 | call to each | block | | local_dataflow.rb:19:10:19:14 | array | local_dataflow.rb:19:1:21:3 | call to each | self | | local_dataflow.rb:20:6:20:6 | x | local_dataflow.rb:20:6:20:10 | ... > ... | self | diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index 1b4ac41e00b..62e839d3251 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -2842,6 +2842,7 @@ | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | | local_dataflow.rb:1:1:7:3 | synthetic *args | local_dataflow.rb:1:9:1:9 | a | +| local_dataflow.rb:1:1:150:3 | | local_dataflow.rb:10:5:13:3 | x | | local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a | @@ -2870,31 +2871,57 @@ | local_dataflow.rb:9:9:9:15 | Array | local_dataflow.rb:9:9:9:15 | call to [] | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | +| local_dataflow.rb:10:5:13:3 | ... | local_dataflow.rb:10:1:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:10:5:13:3 | if ... | | local_dataflow.rb:10:5:13:3 | self | local_dataflow.rb:11:1:11:2 | self | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:15:1:17:3 | x | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x | -| local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:1:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:5:13:3 | ... | +| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [false] ! ... | +| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [true] ! ... | +| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | x | | local_dataflow.rb:10:5:13:3 | synthetic *args | local_dataflow.rb:10:5:13:3 | __synth__0__1 | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | defined? ... | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | phi | | local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:14:10:18 | [post] array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:11:1:11:2 | [post] self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:12:3:12:5 | self | +| local_dataflow.rb:15:1:17:3 | ... = ... | local_dataflow.rb:15:1:17:3 | if ... | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:19:1:21:3 | x | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x | +| local_dataflow.rb:15:1:17:3 | call to each | local_dataflow.rb:15:1:17:3 | ... | +| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [false] ! ... | +| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [true] ! ... | +| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | ... = ... | +| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | x | | local_dataflow.rb:15:1:17:3 | synthetic *args | local_dataflow.rb:15:1:17:3 | __synth__0__1 | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | defined? ... | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | phi | | local_dataflow.rb:15:10:15:14 | [post] array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:16:9:16:10 | 10 | local_dataflow.rb:16:3:16:10 | break | +| local_dataflow.rb:19:1:21:3 | ... = ... | local_dataflow.rb:19:1:21:3 | if ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x | +| local_dataflow.rb:19:1:21:3 | call to each | local_dataflow.rb:19:1:21:3 | ... | +| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [false] ! ... | +| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [true] ! ... | +| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | ... = ... | +| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | x | | local_dataflow.rb:19:1:21:3 | synthetic *args | local_dataflow.rb:19:1:21:3 | __synth__0__1 | +| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | defined? ... | +| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | phi | | local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:20:6:20:6 | x | | local_dataflow.rb:20:6:20:6 | x | local_dataflow.rb:20:6:20:10 | ... > ... | | local_dataflow.rb:20:10:20:10 | 1 | local_dataflow.rb:20:6:20:10 | ... > ... | diff --git a/ruby/ql/test/library-tests/variables/ssa.expected b/ruby/ql/test/library-tests/variables/ssa.expected index 962cd733a08..f06c0032136 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -127,6 +127,8 @@ definition | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | | ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | +| ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | +| ssa.rb:26:3:28:5 | phi | ssa.rb:26:7:26:10 | elem | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:32:1:36:3 | self (m3) | ssa.rb:32:1:36:3 | self | | ssa.rb:33:16:35:5 | self | ssa.rb:32:1:36:3 | self | @@ -316,6 +318,7 @@ read | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | +| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | @@ -470,6 +473,7 @@ firstRead | ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | +| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | @@ -621,6 +625,7 @@ lastRead | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | +| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | @@ -736,6 +741,8 @@ phi | ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:5 | i | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | +| ssa.rb:26:3:28:5 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | | +| ssa.rb:26:3:28:5 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:3 | x | | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | | diff --git a/ruby/ql/test/library-tests/variables/varaccess.expected b/ruby/ql/test/library-tests/variables/varaccess.expected index cb643bb4233..228c7cc049c 100644 --- a/ruby/ql/test/library-tests/variables/varaccess.expected +++ b/ruby/ql/test/library-tests/variables/varaccess.expected @@ -225,6 +225,8 @@ variableAccess | ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | | ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | | ssa.rb:26:15:26:22 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 | | ssa.rb:27:5:27:13 | self | ssa.rb:25:1:30:3 | self | ssa.rb:25:1:30:3 | m2 | @@ -353,6 +355,7 @@ explicitWrite | ssa.rb:10:5:10:5 | i | ssa.rb:10:5:10:9 | ... = ... | | ssa.rb:21:5:21:5 | x | ssa.rb:21:5:21:10 | ... -= ... | | ssa.rb:21:5:21:5 | x | ssa.rb:21:5:21:10 | ... = ... | +| ssa.rb:26:3:28:5 | elem | ssa.rb:26:3:28:5 | ... = ... | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | ... = ... | | ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:9 | ... = ... | | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:7 | ... = ... | @@ -567,6 +570,7 @@ readAccess | ssa.rb:20:10:20:10 | x | | ssa.rb:21:5:21:5 | x | | ssa.rb:26:3:28:5 | __synth__0__1 | +| ssa.rb:26:3:28:5 | elem | | ssa.rb:26:15:26:22 | elements | | ssa.rb:27:5:27:13 | self | | ssa.rb:27:10:27:13 | elem | From eac44e89d99cfe69d5e270163c0ad49b0816663c Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 10 Aug 2023 14:21:16 +0200 Subject: [PATCH 19/23] Python: test nice locations there are errors both on lines 2 and 3 due to locations being computed wrongly. --- .../library-tests/locations/imports/import_statements.py | 4 ++++ .../test/library-tests/locations/imports/imports.expected | 8 ++++++++ python/ql/test/library-tests/locations/imports/imports.ql | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 python/ql/test/library-tests/locations/imports/import_statements.py create mode 100644 python/ql/test/library-tests/locations/imports/imports.expected create mode 100644 python/ql/test/library-tests/locations/imports/imports.ql diff --git a/python/ql/test/library-tests/locations/imports/import_statements.py b/python/ql/test/library-tests/locations/imports/import_statements.py new file mode 100644 index 00000000000..488f1f4e2be --- /dev/null +++ b/python/ql/test/library-tests/locations/imports/import_statements.py @@ -0,0 +1,4 @@ +from nova.api.openstack.placement import microversion +from nova.api.openstack.placement.objects import resource_provider as rp_obj +from nova.api.openstack.placement.policies import allocation_candidate as \ + policies diff --git a/python/ql/test/library-tests/locations/imports/imports.expected b/python/ql/test/library-tests/locations/imports/imports.expected new file mode 100644 index 00000000000..11de3910d26 --- /dev/null +++ b/python/ql/test/library-tests/locations/imports/imports.expected @@ -0,0 +1,8 @@ +| import_statements.py | 1 | 6 | 1 | 33 | +| import_statements.py | 1 | 42 | 1 | 53 | +| import_statements.py | 2 | 6 | 2 | 41 | +| import_statements.py | 2 | 60 | 2 | 76 | +| import_statements.py | 2 | 71 | 2 | 76 | +| import_statements.py | 3 | 6 | 3 | 42 | +| import_statements.py | 4 | 5 | 4 | 12 | +| import_statements.py | 4 | -7 | 4 | 12 | diff --git a/python/ql/test/library-tests/locations/imports/imports.ql b/python/ql/test/library-tests/locations/imports/imports.ql new file mode 100644 index 00000000000..f19c52e8d0a --- /dev/null +++ b/python/ql/test/library-tests/locations/imports/imports.ql @@ -0,0 +1,6 @@ +import python +import analysis.DefinitionTracking + +from NiceLocationExpr expr, string f, int bl, int bc, int el, int ec +where expr.hasLocationInfo(f, bl, bc, el, ec) +select f, bl, bc, el, ec From e5cd3e8f64e56a253b1a1b516680ed547c78ddbb Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 10 Aug 2023 20:27:06 +0200 Subject: [PATCH 20/23] Python: nice locations for import aliases These were computed wrongly before. --- python/ql/lib/analysis/DefinitionTracking.qll | 11 ++++++++--- .../library-tests/locations/imports/imports.expected | 2 -- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/analysis/DefinitionTracking.qll b/python/ql/lib/analysis/DefinitionTracking.qll index ddc373236f7..6cf9e118681 100644 --- a/python/ql/lib/analysis/DefinitionTracking.qll +++ b/python/ql/lib/analysis/DefinitionTracking.qll @@ -492,9 +492,14 @@ class NiceLocationExpr extends Expr { // for `import xxx` or for `import xxx as yyy`. this.(ImportExpr).getLocation().hasLocationInfo(f, bl, bc, el, ec) or - /* Show y for `y` in `from xxx import y` */ - exists(string name | - name = this.(ImportMember).getName() and + // Show y for `y` in `from xxx import y` + // and y for `yyy as y` in `from xxx import yyy as y`. + exists(string name, Alias alias | + // This alias will always exist, as `from xxx import y` + // is expanded to `from xxx imprt y as y`. + this = alias.getValue() and + name = alias.getAsname().(Name).getId() + | this.(ImportMember).getLocation().hasLocationInfo(f, _, _, el, ec) and bl = el and bc = ec - name.length() + 1 diff --git a/python/ql/test/library-tests/locations/imports/imports.expected b/python/ql/test/library-tests/locations/imports/imports.expected index 11de3910d26..8d2726f748e 100644 --- a/python/ql/test/library-tests/locations/imports/imports.expected +++ b/python/ql/test/library-tests/locations/imports/imports.expected @@ -1,8 +1,6 @@ | import_statements.py | 1 | 6 | 1 | 33 | | import_statements.py | 1 | 42 | 1 | 53 | | import_statements.py | 2 | 6 | 2 | 41 | -| import_statements.py | 2 | 60 | 2 | 76 | | import_statements.py | 2 | 71 | 2 | 76 | | import_statements.py | 3 | 6 | 3 | 42 | | import_statements.py | 4 | 5 | 4 | 12 | -| import_statements.py | 4 | -7 | 4 | 12 | From 3457f23db536581e5da74923ae72d545dc687dc9 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 10 Aug 2023 20:53:43 +0200 Subject: [PATCH 21/23] Python: Add change note --- python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md diff --git a/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md b/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md new file mode 100644 index 00000000000..02872916b51 --- /dev/null +++ b/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed the computation of display locations for imports with aliases. From d2a0b9a66cdfdeba123933351e7391805662cd89 Mon Sep 17 00:00:00 2001 From: yoff Date: Mon, 14 Aug 2023 10:55:00 +0200 Subject: [PATCH 22/23] Update python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md Co-authored-by: Rasmus Wriedt Larsen --- python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md b/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md index 02872916b51..44835fd3b9f 100644 --- a/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md +++ b/python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md @@ -1,4 +1,4 @@ --- category: fix --- -* Fixed the computation of display locations for imports with aliases. +* Fixed the computation of locations for imports with aliases in jump-to-definition. From e96cbeb00a984e9d95da4c0711dcbf1218f5f3a7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 14 Aug 2023 14:37:47 +0200 Subject: [PATCH 23/23] Ruby: Adjust locations of synthesized nodes --- .../codeql/ruby/ast/internal/Synthesis.qll | 32 +++++++++++-- .../test/library-tests/ast/ValueText.expected | 48 +++++++++---------- .../library-tests/ast/calls/calls.expected | 20 ++++---- .../ast/control/ConditionalExpr.expected | 12 ++--- .../ast/control/ControlExpr.expected | 12 ++--- .../controlflow/graph/Nodes.expected | 6 +-- .../dataflow/local/DataflowStep.expected | 30 ++++++------ .../dataflow/local/Nodes.expected | 18 +++---- .../dataflow/local/TaintStep.expected | 48 +++++++++---------- .../test/library-tests/variables/ssa.expected | 14 +++--- .../variables/varaccess.expected | 8 ++-- 11 files changed, 137 insertions(+), 111 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 9cd9b561513..f33fb647bf3 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -1276,13 +1276,19 @@ private module ForLoopDesugar { result.getParent() = getForLoopPatternChild(for) } + /** Holds if `n` is an access to variable `v` in the pattern of `for`. */ + pragma[nomagic] + private predicate forLoopVariableAccess(Ruby::For for, Ruby::AstNode n, VariableReal v) { + n = getForLoopPatternChild(for) and + access(n, v) + } + /** Holds if `v` is the `i`th iteration variable of `for`. */ private predicate forLoopVariable(Ruby::For for, VariableReal v, int i) { v = rank[i + 1](VariableReal v0, Ruby::AstNode n, Location l | - n = getForLoopPatternChild(for) and - l = n.getLocation() and - access(n, v0) + forLoopVariableAccess(for, n, v0) and + l = n.getLocation() | v0 order by l.getStartLine(), l.getStartColumn() ) @@ -1406,6 +1412,18 @@ private module ForLoopDesugar { ) } + pragma[nomagic] + private predicate isDesugaredInitNode(ForExpr for, Variable v, AstNode n) { + exists(StmtSequence seq, AssignExpr ae | + seq = for.getDesugared() and + n = seq.getStmt(_) and + ae = n.(IfExpr).getThen() and + v = ae.getLeftOperand().getAVariable() + ) + or + isDesugaredInitNode(for, v, n.getParent()) + } + private class ForLoopSynthesis extends Synthesis { final override predicate child(AstNode parent, int i, Child child) { forLoopSynthesis(parent, i, child) @@ -1425,6 +1443,14 @@ private module ForLoopDesugar { final override predicate excludeFromControlFlowTree(AstNode n) { n = any(ForExpr for).getBody() } + + final override predicate location(AstNode n, Location l) { + exists(ForExpr for, Ruby::AstNode access, Variable v | + forLoopVariableAccess(toTsFor(for), access, v) and + isDesugaredInitNode(for, v, n) and + l = access.getLocation() + ) + } } } diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index 0c0a78423cf..ff087d7d72d 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -10,8 +10,8 @@ exprValue | calls/calls.rb:26:7:26:7 | 1 | 1 | int | | calls/calls.rb:36:9:36:11 | 100 | 100 | int | | calls/calls.rb:36:14:36:16 | 200 | 200 | int | -| calls/calls.rb:226:1:228:3 | nil | nil | nil | -| calls/calls.rb:229:1:231:3 | nil | nil | nil | +| calls/calls.rb:226:5:226:5 | nil | nil | nil | +| calls/calls.rb:229:5:229:5 | nil | nil | nil | | calls/calls.rb:280:5:280:8 | :blah | :blah | symbol | | calls/calls.rb:281:5:281:8 | :blah | :blah | symbol | | calls/calls.rb:290:11:290:16 | "blah" | blah | string | @@ -59,12 +59,12 @@ exprValue | calls/calls.rb:322:31:322:31 | 1 | 1 | int | | calls/calls.rb:322:37:322:37 | 2 | 2 | int | | calls/calls.rb:330:31:330:37 | "error" | error | string | -| calls/calls.rb:342:1:344:3 | nil | nil | nil | -| calls/calls.rb:342:1:344:3 | nil | nil | nil | -| calls/calls.rb:342:1:344:3 | nil | nil | nil | | calls/calls.rb:342:5:342:5 | 0 | 0 | int | +| calls/calls.rb:342:5:342:5 | nil | nil | nil | | calls/calls.rb:342:8:342:8 | 1 | 1 | int | +| calls/calls.rb:342:8:342:8 | nil | nil | nil | | calls/calls.rb:342:11:342:11 | 2 | 2 | int | +| calls/calls.rb:342:11:342:11 | nil | nil | nil | | calls/calls.rb:342:18:342:18 | 1 | 1 | int | | calls/calls.rb:342:20:342:20 | 2 | 2 | int | | calls/calls.rb:342:22:342:22 | 3 | 3 | int | @@ -335,24 +335,24 @@ exprValue | control/loops.rb:4:5:4:5 | 0 | 0 | int | | control/loops.rb:5:5:5:5 | 0 | 0 | int | | control/loops.rb:6:5:6:5 | 0 | 0 | int | -| control/loops.rb:9:1:12:3 | nil | nil | nil | +| control/loops.rb:9:5:9:5 | nil | nil | nil | | control/loops.rb:9:10:9:10 | 1 | 1 | int | | control/loops.rb:9:13:9:14 | 10 | 10 | int | -| control/loops.rb:16:1:19:3 | nil | nil | nil | +| control/loops.rb:16:5:16:5 | nil | nil | nil | | control/loops.rb:16:10:16:10 | 1 | 1 | int | | control/loops.rb:16:13:16:14 | 10 | 10 | int | -| control/loops.rb:22:1:25:3 | nil | nil | nil | -| control/loops.rb:22:1:25:3 | nil | nil | nil | | control/loops.rb:22:5:22:7 | 0 | 0 | int | +| control/loops.rb:22:5:22:7 | nil | nil | nil | | control/loops.rb:22:10:22:14 | 1 | 1 | int | +| control/loops.rb:22:10:22:14 | nil | nil | nil | | control/loops.rb:22:20:22:22 | :foo | :foo | symbol | | control/loops.rb:22:25:22:25 | 0 | 0 | int | | control/loops.rb:22:28:22:30 | :bar | :bar | symbol | | control/loops.rb:22:33:22:33 | 1 | 1 | int | -| control/loops.rb:28:1:32:3 | nil | nil | nil | -| control/loops.rb:28:1:32:3 | nil | nil | nil | | control/loops.rb:28:6:28:8 | 0 | 0 | int | +| control/loops.rb:28:6:28:8 | nil | nil | nil | | control/loops.rb:28:11:28:15 | 1 | 1 | int | +| control/loops.rb:28:11:28:15 | nil | nil | nil | | control/loops.rb:28:22:28:24 | :foo | :foo | symbol | | control/loops.rb:28:27:28:27 | 0 | 0 | int | | control/loops.rb:28:30:28:32 | :bar | :bar | symbol | @@ -376,7 +376,7 @@ exprValue | control/loops.rb:66:11:66:11 | y | 0 | int | | erb/template.html.erb:19:5:19:17 | "hello world" | hello world | string | | erb/template.html.erb:25:9:25:10 | "" | | string | -| erb/template.html.erb:27:6:31:8 | nil | nil | nil | +| erb/template.html.erb:27:10:27:10 | nil | nil | nil | | erb/template.html.erb:27:16:27:20 | "foo" | foo | string | | erb/template.html.erb:27:23:27:27 | "bar" | bar | string | | erb/template.html.erb:27:30:27:34 | "baz" | baz | string | @@ -946,8 +946,8 @@ exprCfgNodeValue | calls/calls.rb:26:7:26:7 | 1 | 1 | int | | calls/calls.rb:36:9:36:11 | 100 | 100 | int | | calls/calls.rb:36:14:36:16 | 200 | 200 | int | -| calls/calls.rb:226:1:228:3 | nil | nil | nil | -| calls/calls.rb:229:1:231:3 | nil | nil | nil | +| calls/calls.rb:226:5:226:5 | nil | nil | nil | +| calls/calls.rb:229:5:229:5 | nil | nil | nil | | calls/calls.rb:280:5:280:8 | :blah | :blah | symbol | | calls/calls.rb:281:5:281:8 | :blah | :blah | symbol | | calls/calls.rb:290:11:290:16 | "blah" | blah | string | @@ -995,12 +995,12 @@ exprCfgNodeValue | calls/calls.rb:322:31:322:31 | 1 | 1 | int | | calls/calls.rb:322:37:322:37 | 2 | 2 | int | | calls/calls.rb:330:31:330:37 | "error" | error | string | -| calls/calls.rb:342:1:344:3 | nil | nil | nil | -| calls/calls.rb:342:1:344:3 | nil | nil | nil | -| calls/calls.rb:342:1:344:3 | nil | nil | nil | | calls/calls.rb:342:5:342:5 | 0 | 0 | int | +| calls/calls.rb:342:5:342:5 | nil | nil | nil | | calls/calls.rb:342:8:342:8 | 1 | 1 | int | +| calls/calls.rb:342:8:342:8 | nil | nil | nil | | calls/calls.rb:342:11:342:11 | 2 | 2 | int | +| calls/calls.rb:342:11:342:11 | nil | nil | nil | | calls/calls.rb:342:18:342:18 | 1 | 1 | int | | calls/calls.rb:342:20:342:20 | 2 | 2 | int | | calls/calls.rb:342:22:342:22 | 3 | 3 | int | @@ -1243,24 +1243,24 @@ exprCfgNodeValue | control/loops.rb:4:5:4:5 | 0 | 0 | int | | control/loops.rb:5:5:5:5 | 0 | 0 | int | | control/loops.rb:6:5:6:5 | 0 | 0 | int | -| control/loops.rb:9:1:12:3 | nil | nil | nil | +| control/loops.rb:9:5:9:5 | nil | nil | nil | | control/loops.rb:9:10:9:10 | 1 | 1 | int | | control/loops.rb:9:13:9:14 | 10 | 10 | int | -| control/loops.rb:16:1:19:3 | nil | nil | nil | +| control/loops.rb:16:5:16:5 | nil | nil | nil | | control/loops.rb:16:10:16:10 | 1 | 1 | int | | control/loops.rb:16:13:16:14 | 10 | 10 | int | -| control/loops.rb:22:1:25:3 | nil | nil | nil | -| control/loops.rb:22:1:25:3 | nil | nil | nil | | control/loops.rb:22:5:22:7 | 0 | 0 | int | +| control/loops.rb:22:5:22:7 | nil | nil | nil | | control/loops.rb:22:10:22:14 | 1 | 1 | int | +| control/loops.rb:22:10:22:14 | nil | nil | nil | | control/loops.rb:22:20:22:22 | :foo | :foo | symbol | | control/loops.rb:22:25:22:25 | 0 | 0 | int | | control/loops.rb:22:28:22:30 | :bar | :bar | symbol | | control/loops.rb:22:33:22:33 | 1 | 1 | int | -| control/loops.rb:28:1:32:3 | nil | nil | nil | -| control/loops.rb:28:1:32:3 | nil | nil | nil | | control/loops.rb:28:6:28:8 | 0 | 0 | int | +| control/loops.rb:28:6:28:8 | nil | nil | nil | | control/loops.rb:28:11:28:15 | 1 | 1 | int | +| control/loops.rb:28:11:28:15 | nil | nil | nil | | control/loops.rb:28:22:28:24 | :foo | :foo | symbol | | control/loops.rb:28:27:28:27 | 0 | 0 | int | | control/loops.rb:28:30:28:32 | :bar | :bar | symbol | @@ -1284,7 +1284,7 @@ exprCfgNodeValue | control/loops.rb:66:11:66:11 | y | 0 | int | | erb/template.html.erb:19:5:19:17 | "hello world" | hello world | string | | erb/template.html.erb:25:9:25:10 | "" | | string | -| erb/template.html.erb:27:6:31:8 | nil | nil | nil | +| erb/template.html.erb:27:10:27:10 | nil | nil | nil | | erb/template.html.erb:27:16:27:20 | "foo" | foo | string | | erb/template.html.erb:27:23:27:27 | "bar" | bar | string | | erb/template.html.erb:27:30:27:34 | "baz" | baz | string | diff --git a/ruby/ql/test/library-tests/ast/calls/calls.expected b/ruby/ql/test/library-tests/ast/calls/calls.expected index ff8ef702c34..da4849487f0 100644 --- a/ruby/ql/test/library-tests/ast/calls/calls.expected +++ b/ruby/ql/test/library-tests/ast/calls/calls.expected @@ -250,14 +250,14 @@ callsWithReceiver | calls.rb:222:11:222:13 | call to foo | calls.rb:222:11:222:13 | self | | calls.rb:223:1:223:6 | call to bar | calls.rb:223:1:223:1 | X | | calls.rb:223:14:223:19 | call to foo | calls.rb:223:14:223:14 | X | -| calls.rb:226:1:228:3 | ! ... | calls.rb:226:1:228:3 | defined? ... | | calls.rb:226:1:228:3 | call to each | calls.rb:226:10:226:12 | call to bar | -| calls.rb:226:1:228:3 | defined? ... | calls.rb:226:1:228:3 | x | +| calls.rb:226:5:226:5 | ! ... | calls.rb:226:5:226:5 | defined? ... | +| calls.rb:226:5:226:5 | defined? ... | calls.rb:226:5:226:5 | x | | calls.rb:226:10:226:12 | call to bar | calls.rb:226:10:226:12 | self | | calls.rb:227:3:227:5 | call to baz | calls.rb:227:3:227:5 | self | -| calls.rb:229:1:231:3 | ! ... | calls.rb:229:1:231:3 | defined? ... | | calls.rb:229:1:231:3 | call to each | calls.rb:229:10:229:15 | call to bar | -| calls.rb:229:1:231:3 | defined? ... | calls.rb:229:1:231:3 | x | +| calls.rb:229:5:229:5 | ! ... | calls.rb:229:5:229:5 | defined? ... | +| calls.rb:229:5:229:5 | defined? ... | calls.rb:229:5:229:5 | x | | calls.rb:229:10:229:15 | call to bar | calls.rb:229:10:229:10 | X | | calls.rb:230:3:230:8 | call to baz | calls.rb:230:3:230:3 | X | | calls.rb:234:1:234:3 | call to foo | calls.rb:234:1:234:3 | self | @@ -378,17 +378,17 @@ callsWithReceiver | calls.rb:330:13:330:15 | call to bar | calls.rb:330:13:330:15 | self | | calls.rb:330:25:330:37 | call to print | calls.rb:330:25:330:37 | self | | calls.rb:338:3:338:13 | call to bar | calls.rb:338:3:338:13 | self | -| calls.rb:342:1:344:3 | ! ... | calls.rb:342:1:344:3 | defined? ... | -| calls.rb:342:1:344:3 | ! ... | calls.rb:342:1:344:3 | defined? ... | -| calls.rb:342:1:344:3 | ! ... | calls.rb:342:1:344:3 | defined? ... | | calls.rb:342:1:344:3 | * ... | calls.rb:342:1:344:3 | __synth__0__1 | | calls.rb:342:1:344:3 | call to each | calls.rb:342:16:342:33 | [...] | -| calls.rb:342:1:344:3 | defined? ... | calls.rb:342:1:344:3 | x | -| calls.rb:342:1:344:3 | defined? ... | calls.rb:342:1:344:3 | y | -| calls.rb:342:1:344:3 | defined? ... | calls.rb:342:1:344:3 | z | +| calls.rb:342:5:342:5 | ! ... | calls.rb:342:5:342:5 | defined? ... | | calls.rb:342:5:342:5 | call to [] | calls.rb:342:5:342:5 | __synth__3__1 | +| calls.rb:342:5:342:5 | defined? ... | calls.rb:342:5:342:5 | x | +| calls.rb:342:8:342:8 | ! ... | calls.rb:342:8:342:8 | defined? ... | | calls.rb:342:8:342:8 | call to [] | calls.rb:342:8:342:8 | __synth__3__1 | +| calls.rb:342:8:342:8 | defined? ... | calls.rb:342:8:342:8 | y | +| calls.rb:342:11:342:11 | ! ... | calls.rb:342:11:342:11 | defined? ... | | calls.rb:342:11:342:11 | call to [] | calls.rb:342:11:342:11 | __synth__3__1 | +| calls.rb:342:11:342:11 | defined? ... | calls.rb:342:11:342:11 | z | | calls.rb:342:16:342:33 | call to [] | calls.rb:342:16:342:33 | Array | | calls.rb:342:17:342:23 | call to [] | calls.rb:342:17:342:23 | Array | | calls.rb:342:26:342:32 | call to [] | calls.rb:342:26:342:32 | Array | diff --git a/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected b/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected index 67cee0cd160..db7cd1957fb 100644 --- a/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected +++ b/ruby/ql/test/library-tests/ast/control/ConditionalExpr.expected @@ -22,12 +22,12 @@ conditionalExprs | conditionals.rb:61:1:64:3 | if ... | IfExpr | conditionals.rb:61:4:61:8 | ... > ... | conditionals.rb:63:1:63:4 | else ... | false | | conditionals.rb:67:1:70:3 | if ... | IfExpr | conditionals.rb:67:4:67:8 | ... > ... | conditionals.rb:67:10:67:13 | then ... | true | | conditionals.rb:67:1:70:3 | if ... | IfExpr | conditionals.rb:67:4:67:8 | ... > ... | conditionals.rb:68:1:69:5 | else ... | false | -| loops.rb:9:1:12:3 | if ... | IfExpr | loops.rb:9:1:12:3 | ! ... | loops.rb:9:1:12:3 | ... = ... | true | -| loops.rb:16:1:19:3 | if ... | IfExpr | loops.rb:16:1:19:3 | ! ... | loops.rb:16:1:19:3 | ... = ... | true | -| loops.rb:22:1:25:3 | if ... | IfExpr | loops.rb:22:1:25:3 | ! ... | loops.rb:22:1:25:3 | ... = ... | true | -| loops.rb:22:1:25:3 | if ... | IfExpr | loops.rb:22:1:25:3 | ! ... | loops.rb:22:1:25:3 | ... = ... | true | -| loops.rb:28:1:32:3 | if ... | IfExpr | loops.rb:28:1:32:3 | ! ... | loops.rb:28:1:32:3 | ... = ... | true | -| loops.rb:28:1:32:3 | if ... | IfExpr | loops.rb:28:1:32:3 | ! ... | loops.rb:28:1:32:3 | ... = ... | true | +| loops.rb:9:5:9:5 | if ... | IfExpr | loops.rb:9:5:9:5 | ! ... | loops.rb:9:5:9:5 | ... = ... | true | +| loops.rb:16:5:16:5 | if ... | IfExpr | loops.rb:16:5:16:5 | ! ... | loops.rb:16:5:16:5 | ... = ... | true | +| loops.rb:22:5:22:7 | if ... | IfExpr | loops.rb:22:5:22:7 | ! ... | loops.rb:22:5:22:7 | ... = ... | true | +| loops.rb:22:10:22:14 | if ... | IfExpr | loops.rb:22:10:22:14 | ! ... | loops.rb:22:10:22:14 | ... = ... | true | +| loops.rb:28:6:28:8 | if ... | IfExpr | loops.rb:28:6:28:8 | ! ... | loops.rb:28:6:28:8 | ... = ... | true | +| loops.rb:28:11:28:15 | if ... | IfExpr | loops.rb:28:11:28:15 | ! ... | loops.rb:28:11:28:15 | ... = ... | true | ifExprs | conditionals.rb:10:1:12:3 | if ... | IfExpr | conditionals.rb:10:4:10:8 | ... > ... | conditionals.rb:10:10:11:5 | then ... | (none) | false | | conditionals.rb:15:1:19:3 | if ... | IfExpr | conditionals.rb:15:4:15:9 | ... == ... | conditionals.rb:15:10:16:5 | then ... | else ... | false | diff --git a/ruby/ql/test/library-tests/ast/control/ControlExpr.expected b/ruby/ql/test/library-tests/ast/control/ControlExpr.expected index 58e30085922..c4d09535ccf 100644 --- a/ruby/ql/test/library-tests/ast/control/ControlExpr.expected +++ b/ruby/ql/test/library-tests/ast/control/ControlExpr.expected @@ -27,15 +27,15 @@ | conditionals.rb:61:1:64:3 | if ... | IfExpr | | conditionals.rb:67:1:70:3 | if ... | IfExpr | | loops.rb:9:1:12:3 | for ... in ... | ForExpr | -| loops.rb:9:1:12:3 | if ... | IfExpr | +| loops.rb:9:5:9:5 | if ... | IfExpr | | loops.rb:16:1:19:3 | for ... in ... | ForExpr | -| loops.rb:16:1:19:3 | if ... | IfExpr | +| loops.rb:16:5:16:5 | if ... | IfExpr | | loops.rb:22:1:25:3 | for ... in ... | ForExpr | -| loops.rb:22:1:25:3 | if ... | IfExpr | -| loops.rb:22:1:25:3 | if ... | IfExpr | +| loops.rb:22:5:22:7 | if ... | IfExpr | +| loops.rb:22:10:22:14 | if ... | IfExpr | | loops.rb:28:1:32:3 | for ... in ... | ForExpr | -| loops.rb:28:1:32:3 | if ... | IfExpr | -| loops.rb:28:1:32:3 | if ... | IfExpr | +| loops.rb:28:6:28:8 | if ... | IfExpr | +| loops.rb:28:11:28:15 | if ... | IfExpr | | loops.rb:35:1:39:3 | while ... | WhileExpr | | loops.rb:42:1:45:3 | while ... | WhileExpr | | loops.rb:48:1:48:19 | ... while ... | WhileModifierExpr | diff --git a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected index 42b7ed153d3..f7bc8a1b1e7 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -25,10 +25,10 @@ callsWithNoArguments | cfg.rb:60:17:60:17 | call to b | | cfg.rb:62:7:62:12 | * ... | | cfg.rb:62:17:62:27 | * ... | -| cfg.rb:90:1:93:3 | [false] ! ... | -| cfg.rb:90:1:93:3 | [true] ! ... | | cfg.rb:90:1:93:3 | call to each | -| cfg.rb:90:1:93:3 | defined? ... | +| cfg.rb:90:5:90:5 | [false] ! ... | +| cfg.rb:90:5:90:5 | [true] ! ... | +| cfg.rb:90:5:90:5 | defined? ... | | cfg.rb:98:10:98:15 | ** ... | | cfg.rb:98:30:98:35 | ** ... | | cfg.rb:138:17:138:23 | * ... | diff --git a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected index 064e9a5482e..cbba246c74b 100644 --- a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected @@ -2399,7 +2399,7 @@ | UseUseExplosion.rb:24:5:25:7 | use | UseUseExplosion.rb:1:1:26:3 | C | | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | -| local_dataflow.rb:1:1:150:3 | | local_dataflow.rb:10:5:13:3 | x | +| local_dataflow.rb:1:1:150:3 | | local_dataflow.rb:10:9:10:9 | x | | local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a | @@ -2426,44 +2426,44 @@ | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | | local_dataflow.rb:10:5:13:3 | ... | local_dataflow.rb:10:1:13:3 | ... = ... | -| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:10:5:13:3 | if ... | | local_dataflow.rb:10:5:13:3 | self | local_dataflow.rb:11:1:11:2 | self | -| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:15:1:17:3 | x | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:15:5:15:5 | x | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x | | local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:5:13:3 | ... | -| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | ... = ... | -| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | x | -| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | phi | +| local_dataflow.rb:10:9:10:9 | ... = ... | local_dataflow.rb:10:9:10:9 | if ... | +| local_dataflow.rb:10:9:10:9 | nil | local_dataflow.rb:10:9:10:9 | ... = ... | +| local_dataflow.rb:10:9:10:9 | nil | local_dataflow.rb:10:9:10:9 | x | +| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:10:9:10:9 | phi | | local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:14:10:18 | [post] array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:11:1:11:2 | [post] self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:12:3:12:5 | self | -| local_dataflow.rb:15:1:17:3 | ... = ... | local_dataflow.rb:15:1:17:3 | if ... | -| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:19:1:21:3 | x | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:19:5:19:5 | x | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x | | local_dataflow.rb:15:1:17:3 | call to each | local_dataflow.rb:15:1:17:3 | ... | -| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | ... = ... | -| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | x | -| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | phi | +| local_dataflow.rb:15:5:15:5 | ... = ... | local_dataflow.rb:15:5:15:5 | if ... | +| local_dataflow.rb:15:5:15:5 | nil | local_dataflow.rb:15:5:15:5 | ... = ... | +| local_dataflow.rb:15:5:15:5 | nil | local_dataflow.rb:15:5:15:5 | x | +| local_dataflow.rb:15:5:15:5 | x | local_dataflow.rb:15:5:15:5 | phi | | local_dataflow.rb:15:10:15:14 | [post] array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:16:9:16:10 | 10 | local_dataflow.rb:16:3:16:10 | break | -| local_dataflow.rb:19:1:21:3 | ... = ... | local_dataflow.rb:19:1:21:3 | if ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x | | local_dataflow.rb:19:1:21:3 | call to each | local_dataflow.rb:19:1:21:3 | ... | -| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | ... = ... | -| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | x | -| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | phi | +| local_dataflow.rb:19:5:19:5 | ... = ... | local_dataflow.rb:19:5:19:5 | if ... | +| local_dataflow.rb:19:5:19:5 | nil | local_dataflow.rb:19:5:19:5 | ... = ... | +| local_dataflow.rb:19:5:19:5 | nil | local_dataflow.rb:19:5:19:5 | x | +| local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:19:5:19:5 | phi | | local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:20:6:20:6 | x | | local_dataflow.rb:24:2:24:8 | break | local_dataflow.rb:23:1:25:3 | while ... | | local_dataflow.rb:24:8:24:8 | 5 | local_dataflow.rb:24:2:24:8 | break | diff --git a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected index b6808099a0b..3b7dd05902d 100644 --- a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected +++ b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected @@ -831,23 +831,23 @@ arg | local_dataflow.rb:9:10:9:10 | 1 | local_dataflow.rb:9:9:9:15 | call to [] | position 0 | | local_dataflow.rb:9:12:9:12 | 2 | local_dataflow.rb:9:9:9:15 | call to [] | position 1 | | local_dataflow.rb:9:14:9:14 | 3 | local_dataflow.rb:9:9:9:15 | call to [] | position 2 | -| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [false] ! ... | self | -| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [true] ! ... | self | -| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | defined? ... | self | | local_dataflow.rb:10:5:13:3 | { ... } | local_dataflow.rb:10:5:13:3 | call to each | block | +| local_dataflow.rb:10:9:10:9 | defined? ... | local_dataflow.rb:10:9:10:9 | [false] ! ... | self | +| local_dataflow.rb:10:9:10:9 | defined? ... | local_dataflow.rb:10:9:10:9 | [true] ! ... | self | +| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:10:9:10:9 | defined? ... | self | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:10:5:13:3 | call to each | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:11:1:11:2 | call to do | self | | local_dataflow.rb:12:3:12:5 | self | local_dataflow.rb:12:3:12:5 | call to p | self | | local_dataflow.rb:12:5:12:5 | x | local_dataflow.rb:12:3:12:5 | call to p | position 0 | -| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [false] ! ... | self | -| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [true] ! ... | self | -| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | defined? ... | self | | local_dataflow.rb:15:1:17:3 | { ... } | local_dataflow.rb:15:1:17:3 | call to each | block | +| local_dataflow.rb:15:5:15:5 | defined? ... | local_dataflow.rb:15:5:15:5 | [false] ! ... | self | +| local_dataflow.rb:15:5:15:5 | defined? ... | local_dataflow.rb:15:5:15:5 | [true] ! ... | self | +| local_dataflow.rb:15:5:15:5 | x | local_dataflow.rb:15:5:15:5 | defined? ... | self | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:15:1:17:3 | call to each | self | -| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [false] ! ... | self | -| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [true] ! ... | self | -| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | defined? ... | self | | local_dataflow.rb:19:1:21:3 | { ... } | local_dataflow.rb:19:1:21:3 | call to each | block | +| local_dataflow.rb:19:5:19:5 | defined? ... | local_dataflow.rb:19:5:19:5 | [false] ! ... | self | +| local_dataflow.rb:19:5:19:5 | defined? ... | local_dataflow.rb:19:5:19:5 | [true] ! ... | self | +| local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:19:5:19:5 | defined? ... | self | | local_dataflow.rb:19:10:19:14 | array | local_dataflow.rb:19:1:21:3 | call to each | self | | local_dataflow.rb:20:6:20:6 | x | local_dataflow.rb:20:6:20:10 | ... > ... | self | | local_dataflow.rb:20:10:20:10 | 1 | local_dataflow.rb:20:6:20:10 | ... > ... | position 0 | diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index 62e839d3251..237c067be1b 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -2842,7 +2842,7 @@ | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | | local_dataflow.rb:1:1:7:3 | synthetic *args | local_dataflow.rb:1:9:1:9 | a | -| local_dataflow.rb:1:1:150:3 | | local_dataflow.rb:10:5:13:3 | x | +| local_dataflow.rb:1:1:150:3 | | local_dataflow.rb:10:9:10:9 | x | | local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a | @@ -2872,56 +2872,56 @@ | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | | local_dataflow.rb:10:5:13:3 | ... | local_dataflow.rb:10:1:13:3 | ... = ... | -| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:10:5:13:3 | if ... | | local_dataflow.rb:10:5:13:3 | self | local_dataflow.rb:11:1:11:2 | self | -| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:15:1:17:3 | x | +| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:15:5:15:5 | x | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x | | local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:5:13:3 | ... | -| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [false] ! ... | -| local_dataflow.rb:10:5:13:3 | defined? ... | local_dataflow.rb:10:5:13:3 | [true] ! ... | -| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | ... = ... | -| local_dataflow.rb:10:5:13:3 | nil | local_dataflow.rb:10:5:13:3 | x | | local_dataflow.rb:10:5:13:3 | synthetic *args | local_dataflow.rb:10:5:13:3 | __synth__0__1 | -| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | defined? ... | -| local_dataflow.rb:10:5:13:3 | x | local_dataflow.rb:10:5:13:3 | phi | +| local_dataflow.rb:10:9:10:9 | ... = ... | local_dataflow.rb:10:9:10:9 | if ... | +| local_dataflow.rb:10:9:10:9 | defined? ... | local_dataflow.rb:10:9:10:9 | [false] ! ... | +| local_dataflow.rb:10:9:10:9 | defined? ... | local_dataflow.rb:10:9:10:9 | [true] ! ... | +| local_dataflow.rb:10:9:10:9 | nil | local_dataflow.rb:10:9:10:9 | ... = ... | +| local_dataflow.rb:10:9:10:9 | nil | local_dataflow.rb:10:9:10:9 | x | +| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:10:9:10:9 | defined? ... | +| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:10:9:10:9 | phi | | local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:14:10:18 | [post] array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:11:1:11:2 | [post] self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:12:3:12:5 | self | -| local_dataflow.rb:15:1:17:3 | ... = ... | local_dataflow.rb:15:1:17:3 | if ... | -| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:19:1:21:3 | x | +| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:19:5:19:5 | x | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x | | local_dataflow.rb:15:1:17:3 | call to each | local_dataflow.rb:15:1:17:3 | ... | -| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [false] ! ... | -| local_dataflow.rb:15:1:17:3 | defined? ... | local_dataflow.rb:15:1:17:3 | [true] ! ... | -| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | ... = ... | -| local_dataflow.rb:15:1:17:3 | nil | local_dataflow.rb:15:1:17:3 | x | | local_dataflow.rb:15:1:17:3 | synthetic *args | local_dataflow.rb:15:1:17:3 | __synth__0__1 | -| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | defined? ... | -| local_dataflow.rb:15:1:17:3 | x | local_dataflow.rb:15:1:17:3 | phi | +| local_dataflow.rb:15:5:15:5 | ... = ... | local_dataflow.rb:15:5:15:5 | if ... | +| local_dataflow.rb:15:5:15:5 | defined? ... | local_dataflow.rb:15:5:15:5 | [false] ! ... | +| local_dataflow.rb:15:5:15:5 | defined? ... | local_dataflow.rb:15:5:15:5 | [true] ! ... | +| local_dataflow.rb:15:5:15:5 | nil | local_dataflow.rb:15:5:15:5 | ... = ... | +| local_dataflow.rb:15:5:15:5 | nil | local_dataflow.rb:15:5:15:5 | x | +| local_dataflow.rb:15:5:15:5 | x | local_dataflow.rb:15:5:15:5 | defined? ... | +| local_dataflow.rb:15:5:15:5 | x | local_dataflow.rb:15:5:15:5 | phi | | local_dataflow.rb:15:10:15:14 | [post] array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:16:9:16:10 | 10 | local_dataflow.rb:16:3:16:10 | break | -| local_dataflow.rb:19:1:21:3 | ... = ... | local_dataflow.rb:19:1:21:3 | if ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x | | local_dataflow.rb:19:1:21:3 | call to each | local_dataflow.rb:19:1:21:3 | ... | -| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [false] ! ... | -| local_dataflow.rb:19:1:21:3 | defined? ... | local_dataflow.rb:19:1:21:3 | [true] ! ... | -| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | ... = ... | -| local_dataflow.rb:19:1:21:3 | nil | local_dataflow.rb:19:1:21:3 | x | | local_dataflow.rb:19:1:21:3 | synthetic *args | local_dataflow.rb:19:1:21:3 | __synth__0__1 | -| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | defined? ... | -| local_dataflow.rb:19:1:21:3 | x | local_dataflow.rb:19:1:21:3 | phi | +| local_dataflow.rb:19:5:19:5 | ... = ... | local_dataflow.rb:19:5:19:5 | if ... | +| local_dataflow.rb:19:5:19:5 | defined? ... | local_dataflow.rb:19:5:19:5 | [false] ! ... | +| local_dataflow.rb:19:5:19:5 | defined? ... | local_dataflow.rb:19:5:19:5 | [true] ! ... | +| local_dataflow.rb:19:5:19:5 | nil | local_dataflow.rb:19:5:19:5 | ... = ... | +| local_dataflow.rb:19:5:19:5 | nil | local_dataflow.rb:19:5:19:5 | x | +| local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:19:5:19:5 | defined? ... | +| local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:19:5:19:5 | phi | | local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:20:6:20:6 | x | | local_dataflow.rb:20:6:20:6 | x | local_dataflow.rb:20:6:20:10 | ... > ... | | local_dataflow.rb:20:10:20:10 | 1 | local_dataflow.rb:20:6:20:10 | ... > ... | diff --git a/ruby/ql/test/library-tests/variables/ssa.expected b/ruby/ql/test/library-tests/variables/ssa.expected index f06c0032136..f0a3e20ced1 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -127,9 +127,9 @@ definition | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | | ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | -| ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | -| ssa.rb:26:3:28:5 | phi | ssa.rb:26:7:26:10 | elem | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | +| ssa.rb:26:7:26:10 | phi | ssa.rb:26:7:26:10 | elem | | ssa.rb:32:1:36:3 | self (m3) | ssa.rb:32:1:36:3 | self | | ssa.rb:33:16:35:5 | self | ssa.rb:32:1:36:3 | self | | ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | @@ -318,7 +318,7 @@ read | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | -| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | +| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | @@ -473,7 +473,7 @@ firstRead | ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | -| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | +| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | @@ -625,7 +625,7 @@ lastRead | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | -| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | +| ssa.rb:25:1:30:3 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | | ssa.rb:26:3:28:5 | self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | @@ -741,8 +741,8 @@ phi | ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:5 | i | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | -| ssa.rb:26:3:28:5 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | | -| ssa.rb:26:3:28:5 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | elem | +| ssa.rb:26:7:26:10 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | | +| ssa.rb:26:7:26:10 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:3 | x | | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | | diff --git a/ruby/ql/test/library-tests/variables/varaccess.expected b/ruby/ql/test/library-tests/variables/varaccess.expected index 228c7cc049c..0389b0856d3 100644 --- a/ruby/ql/test/library-tests/variables/varaccess.expected +++ b/ruby/ql/test/library-tests/variables/varaccess.expected @@ -225,8 +225,8 @@ variableAccess | ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | | ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 | -| ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | -| ssa.rb:26:3:28:5 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | | ssa.rb:26:15:26:22 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 | | ssa.rb:27:5:27:13 | self | ssa.rb:25:1:30:3 | self | ssa.rb:25:1:30:3 | m2 | @@ -355,8 +355,8 @@ explicitWrite | ssa.rb:10:5:10:5 | i | ssa.rb:10:5:10:9 | ... = ... | | ssa.rb:21:5:21:5 | x | ssa.rb:21:5:21:10 | ... -= ... | | ssa.rb:21:5:21:5 | x | ssa.rb:21:5:21:10 | ... = ... | -| ssa.rb:26:3:28:5 | elem | ssa.rb:26:3:28:5 | ... = ... | | ssa.rb:26:7:26:10 | elem | ssa.rb:26:3:28:5 | ... = ... | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | ... = ... | | ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:9 | ... = ... | | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:7 | ... = ... | | ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:19 | ... = ... | @@ -570,7 +570,7 @@ readAccess | ssa.rb:20:10:20:10 | x | | ssa.rb:21:5:21:5 | x | | ssa.rb:26:3:28:5 | __synth__0__1 | -| ssa.rb:26:3:28:5 | elem | +| ssa.rb:26:7:26:10 | elem | | ssa.rb:26:15:26:22 | elements | | ssa.rb:27:5:27:13 | self | | ssa.rb:27:10:27:13 | elem |