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..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,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. 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 15ab5e0c0be..feb7ff473bd 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -140,7 +140,8 @@ 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", 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"] @@ -313,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"] @@ -424,10 +426,8 @@ 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"] - ["java.util", "Set", "remove", "(Object)", "summary", "manual"] - ["java.util", "Set", "removeAll", "(Collection)", "summary", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index c04126d5f7f..b7ef1410bfa 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,15 @@ * 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, but + * points to 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 +68,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 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] diff --git a/java/ql/test/library-tests/dataflow/collections/B.java b/java/ql/test/library-tests/dataflow/collections/B.java index 0bb2b74d749..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]; } @@ -49,96 +50,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,1707 +149,1727 @@ 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 } { - // "java.util;Vector;true;elementAt;(int);;Element of Argument[this];ReturnValue;value;manual", + // "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);;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;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; 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 } 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..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 | 84 | 68 | 152 | 0.5526315789473685 | 0.0 | 0.5526315789473685 | 0.0 | NaN | 0.4473684210526316 | +| 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 | 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..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 @@ -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,5 @@ | 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'. | +| 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 19fdd42dcad..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 @@ -408,4 +408,8 @@ 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|.)+$/; + +var largeUnicode = new RegExp("^\n\u{1F680}(\u{1F680}|.)+X$"); \ No newline at end of file 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/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..44835fd3b9f --- /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 locations for imports with aliases in jump-to-definition. 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..8d2726f748e --- /dev/null +++ b/python/ql/test/library-tests/locations/imports/imports.expected @@ -0,0 +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 | 71 | 2 | 76 | +| import_statements.py | 3 | 6 | 3 | 42 | +| import_statements.py | 4 | 5 | 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 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/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..f33fb647bf3 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,58 +1270,160 @@ 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 `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 | + forLoopVariableAccess(for, n, v0) and + l = n.getLocation() + | + 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)) ) ) ) } + 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) @@ -1338,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/lib/ide-contextual-queries/printCfg.ql b/ruby/ql/lib/ide-contextual-queries/printCfg.ql index 22681eb48f9..c902474a55c 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.ControlFlowGraphImpl::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()) } } 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..ff087d7d72d 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: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 | @@ -58,8 +60,11 @@ exprValue | calls/calls.rb:322:37:322:37 | 2 | 2 | int | | calls/calls.rb:330:31:330:37 | "error" | error | string | | 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 | @@ -330,18 +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: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: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: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: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 | @@ -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: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 | @@ -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: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 | @@ -982,8 +996,11 @@ exprCfgNodeValue | calls/calls.rb:322:37:322:37 | 2 | 2 | int | | calls/calls.rb:330:31:330:37 | "error" | error | string | | 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 | @@ -1226,18 +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: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: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: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: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 | @@ -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: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 628b3578994..da4849487f0 100644 --- a/ruby/ql/test/library-tests/ast/calls/calls.expected +++ b/ruby/ql/test/library-tests/ast/calls/calls.expected @@ -251,9 +251,13 @@ callsWithReceiver | 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 | call to each | calls.rb:226:10:226:12 | call to bar | +| 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 | call to each | calls.rb:229:10:229:15 | call to bar | +| 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 | @@ -376,9 +380,15 @@ callsWithReceiver | 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 | __synth__0__1 | | calls.rb:342:1:344:3 | call to each | calls.rb:342:16:342:33 | [...] | +| 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 3d78655dbbb..db7cd1957fb 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: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 933b4561162..c4d09535ccf 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:5:9:5 | if ... | IfExpr | | loops.rb:16:1:19:3 | for ... in ... | ForExpr | +| loops.rb:16:5:16:5 | if ... | IfExpr | | loops.rb:22:1:25:3 | for ... in ... | ForExpr | +| 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: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/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..f7bc8a1b1e7 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -26,6 +26,9 @@ callsWithNoArguments | cfg.rb:62:7:62:12 | * ... | | cfg.rb:62:17:62:27 | * ... | | cfg.rb:90:1:93:3 | call to each | +| 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 60f62362f75..cbba246c74b 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: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 | @@ -2424,21 +2425,33 @@ | 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 | self | local_dataflow.rb:11:1:11:2 | self | +| 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:1:13:3 | ... = ... | +| local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:5:13:3 | ... | +| 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 | 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: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 | @@ -2446,6 +2459,11 @@ | 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: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 2ac17e470d7..3b7dd05902d 100644 --- a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected +++ b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected @@ -832,13 +832,22 @@ arg | 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 | { ... } | 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 | { ... } | 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 | { ... } | 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 1b4ac41e00b..237c067be1b 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: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 | @@ -2870,23 +2871,41 @@ | 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 | self | local_dataflow.rb:11:1:11:2 | self | +| 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: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 | synthetic *args | local_dataflow.rb:10:5:13:3 | __synth__0__1 | +| 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 | 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 | synthetic *args | local_dataflow.rb:15:1:17:3 | __synth__0__1 | +| 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 | @@ -2894,7 +2913,15 @@ | 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 | synthetic *args | local_dataflow.rb:19:1:21:3 | __synth__0__1 | +| 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 0a0c59a322b..b03f5ea0e02 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -124,6 +124,8 @@ definition | 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: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 | @@ -312,6 +314,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: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 | @@ -466,6 +469,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: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 | @@ -617,6 +621,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: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 | @@ -732,6 +737,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: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 deead16a654..e79f6ca3023 100644 --- a/ruby/ql/test/library-tests/variables/varaccess.expected +++ b/ruby/ql/test/library-tests/variables/varaccess.expected @@ -226,6 +226,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:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | 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 | | ssa.rb:27:10:27:13 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | @@ -354,6 +356,7 @@ explicitWrite | 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: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 | ... = ... | @@ -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: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 | 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..62ecf1e7bba 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. @@ -17,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 = str.regexpReplaceAll("(.|\\s)", "x").length() + } + /** * Gets an approximation for the ASCII code for `char`. * Only the easily printable chars are included (so no newline, tab, null, etc). @@ -189,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() ) @@ -395,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) } @@ -693,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`. */ @@ -701,16 +722,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 + getCodepointLengthForState(s.getValue()) = i + 1 and q2 = after(s) ) ) @@ -811,7 +832,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. @@ -1104,7 +1125,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, getCodepointLengthForCandidate(w) - 1) | + isLikelyRejectable(next) + ) and not getProcessPrevious(fork, _, w) = acceptsAnySuffix() // we stop `process(..)` early if we can, check here if it happened. } @@ -1214,6 +1237,13 @@ 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. + pragma[noinline] + private string getCodePointAtForProcess(string str, int i) { + result = getCodepointAt(str, i) and + isReDoSCandidate(_, 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`. @@ -1223,7 +1253,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. @@ -1232,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`. @@ -1245,7 +1281,7 @@ module Make { or // repeat until fixpoint i = 0 and - result = process(fork, w, w.length() - 1) + result = process(fork, w, getCodepointLengthForCandidate(w) - 1) ) } @@ -1261,7 +1297,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)), _) + } } /** @@ -1305,10 +1343,40 @@ 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(getCodepointAt(s, 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 + 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. */ + private predicate isPrintable(string char) { + exists(ascii(char)) + or + char = "\n\r\t".charAt(_) } /** diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 2314ce4e1fd..c67822520be 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -3,4 +3,5 @@ version: 0.1.3-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..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 @@ -100,6 +100,32 @@ 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) { + 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 = + // 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*", "") +} + /** * Gets the value of 16 to the power of `n`. Holds only for `n` in the range * 0..7 (inclusive). 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:) |