From 851317e34ffbf27c939d4575fa399c7227c85e6e Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 11 Mar 2021 11:42:32 +0000 Subject: [PATCH 001/272] Add models for StrBuilder's fluent methods --- .../semmle/code/java/frameworks/apache/Lang.qll | 9 +++++++++ .../apache-commons-lang3/StrBuilderTest.java | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index deab8f4a692..1ddf8876c3d 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -427,6 +427,15 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { } } +/** + * An Apache Commons-Lang StrBuilder method that returns `this`. + */ +private class ApacheStrBuilderFluentMethod extends FluentMethod { + ApacheStrBuilderFluentMethod() { + this.getReturnType().(RefType).hasQualifiedName("org.apache.commons.lang3.text", "StrBuilder") + } +} + /** * Taint-propagating models for `WordUtils`. */ diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java index bc8887d1150..d460184e176 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java @@ -128,6 +128,20 @@ class StrBuilderTest { StrBuilder sb72 = new StrBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow StrBuilder sb73 = new StrBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow StrBuilder sb74 = new StrBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow + + // Tests for fluent methods (those returning `this`): + + StrBuilder fluentTest = new StrBuilder(); + sink(fluentTest.append("Harmless").append(taint()).append("Also harmless").toString()); // $hasTaintFlow + + StrBuilder fluentBackflowTest = new StrBuilder(); + fluentBackflowTest.append("Harmless").append(taint()).append("Also harmless"); + sink(fluentBackflowTest.toString()); // $hasTaintFlow + + // Test the case where the fluent method contributing taint is at the end of a statement: + StrBuilder fluentBackflowTest2 = new StrBuilder(); + fluentBackflowTest2.append("Harmless").append(taint()); + sink(fluentBackflowTest2.toString()); // $hasTaintFlow } } \ No newline at end of file From 3a274424abc0bdc7b6d84678aa3a9697c9f2ace0 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 11 Mar 2021 13:45:55 +0000 Subject: [PATCH 002/272] Convert fluent method models to csv and generalise to the three different variants of StrBuilder. --- .../code/java/frameworks/apache/Lang.qll | 86 +++++++++++++++++++ .../apache-commons-lang3/StrBuilderTest.java | 62 +++++++++++++ .../StrBuilderTextTest.java | 76 ++++++++++++++++ .../TextStringBuilderTest.java | 76 ++++++++++++++++ 4 files changed, 300 insertions(+) diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index 1ddf8876c3d..2422efc83d9 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -427,6 +427,92 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { } } +private class ApacheStrBuilderFluentMethodsModel extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + "org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendln;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendNull;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;delete;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;replace;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;reverse;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;setLength;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;setNullText;;;Argument[-1];ReturnValue;value", + "org.apache.commons.text;TextStringBuilder;false;trim;;;Argument[-1];ReturnValue;value" + ] + } +} + /** * An Apache Commons-Lang StrBuilder method that returns `this`. */ diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java index d460184e176..0c0e386e9c2 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTest.java @@ -142,6 +142,68 @@ class StrBuilderTest { StrBuilder fluentBackflowTest2 = new StrBuilder(); fluentBackflowTest2.append("Harmless").append(taint()); sink(fluentBackflowTest2.toString()); // $hasTaintFlow + + // Test all fluent methods are passing taint through to their result: + StrBuilder fluentAllMethodsTest = new StrBuilder(taint()); + sink(fluentAllMethodsTest // $hasTaintFlow + .append("text") + .appendAll("text") + .appendFixedWidthPadLeft("text", 4, ' ') + .appendFixedWidthPadRight("text", 4, ' ') + .appendln("text") + .appendNewLine() + .appendNull() + .appendPadding(0, ' ') + .appendSeparator(',') + .appendWithSeparators(new String[] { }, ",") + .delete(0, 0) + .deleteAll(' ') + .deleteCharAt(0) + .deleteFirst("delme") + .ensureCapacity(100) + .insert(1, "insertme") + .minimizeCapacity() + .replace(0, 0, "replacement") + .replaceAll("find", "replace") + .replaceFirst("find", "replace") + .reverse() + .setCharAt(0, 'a') + .setLength(500) + .setNewLineText("newline") + .setNullText("NULL") + .trim()); + + // Test all fluent methods are passing taint back to their qualifier: + StrBuilder fluentAllMethodsTest2 = new StrBuilder(); + fluentAllMethodsTest2 + .append("text") + .appendAll("text") + .appendFixedWidthPadLeft("text", 4, ' ') + .appendFixedWidthPadRight("text", 4, ' ') + .appendln("text") + .appendNewLine() + .appendNull() + .appendPadding(0, ' ') + .appendSeparator(',') + .appendWithSeparators(new String[] { }, ",") + .delete(0, 0) + .deleteAll(' ') + .deleteCharAt(0) + .deleteFirst("delme") + .ensureCapacity(100) + .insert(1, "insertme") + .minimizeCapacity() + .replace(0, 0, "replacement") + .replaceAll("find", "replace") + .replaceFirst("find", "replace") + .reverse() + .setCharAt(0, 'a') + .setLength(500) + .setNewLineText("newline") + .setNullText("NULL") + .trim() + .append(taint()); + sink(fluentAllMethodsTest2); // $hasTaintFlow } } \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTextTest.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTextTest.java index 796900e8a3b..74f0f1d17c9 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTextTest.java +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/StrBuilderTextTest.java @@ -128,6 +128,82 @@ class StrBuilderTextTest { StrBuilder sb72 = new StrBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow StrBuilder sb73 = new StrBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow StrBuilder sb74 = new StrBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow + + // Tests for fluent methods (those returning `this`): + + StrBuilder fluentTest = new StrBuilder(); + sink(fluentTest.append("Harmless").append(taint()).append("Also harmless").toString()); // $hasTaintFlow + + StrBuilder fluentBackflowTest = new StrBuilder(); + fluentBackflowTest.append("Harmless").append(taint()).append("Also harmless"); + sink(fluentBackflowTest.toString()); // $hasTaintFlow + + // Test the case where the fluent method contributing taint is at the end of a statement: + StrBuilder fluentBackflowTest2 = new StrBuilder(); + fluentBackflowTest2.append("Harmless").append(taint()); + sink(fluentBackflowTest2.toString()); // $hasTaintFlow + + // Test all fluent methods are passing taint through to their result: + StrBuilder fluentAllMethodsTest = new StrBuilder(taint()); + sink(fluentAllMethodsTest // $hasTaintFlow + .append("text") + .appendAll("text") + .appendFixedWidthPadLeft("text", 4, ' ') + .appendFixedWidthPadRight("text", 4, ' ') + .appendln("text") + .appendNewLine() + .appendNull() + .appendPadding(0, ' ') + .appendSeparator(',') + .appendWithSeparators(new String[] { }, ",") + .delete(0, 0) + .deleteAll(' ') + .deleteCharAt(0) + .deleteFirst("delme") + .ensureCapacity(100) + .insert(1, "insertme") + .minimizeCapacity() + .replace(0, 0, "replacement") + .replaceAll("find", "replace") + .replaceFirst("find", "replace") + .reverse() + .setCharAt(0, 'a') + .setLength(500) + .setNewLineText("newline") + .setNullText("NULL") + .trim()); + + // Test all fluent methods are passing taint back to their qualifier: + StrBuilder fluentAllMethodsTest2 = new StrBuilder(); + fluentAllMethodsTest2 + .append("text") + .appendAll("text") + .appendFixedWidthPadLeft("text", 4, ' ') + .appendFixedWidthPadRight("text", 4, ' ') + .appendln("text") + .appendNewLine() + .appendNull() + .appendPadding(0, ' ') + .appendSeparator(',') + .appendWithSeparators(new String[] { }, ",") + .delete(0, 0) + .deleteAll(' ') + .deleteCharAt(0) + .deleteFirst("delme") + .ensureCapacity(100) + .insert(1, "insertme") + .minimizeCapacity() + .replace(0, 0, "replacement") + .replaceAll("find", "replace") + .replaceFirst("find", "replace") + .reverse() + .setCharAt(0, 'a') + .setLength(500) + .setNewLineText("newline") + .setNullText("NULL") + .trim() + .append(taint()); + sink(fluentAllMethodsTest2); // $hasTaintFlow } } \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/TextStringBuilderTest.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/TextStringBuilderTest.java index 69db28cb3e9..e490c11c7cb 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/TextStringBuilderTest.java +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/TextStringBuilderTest.java @@ -129,6 +129,82 @@ class TextStringBuilderTest { TextStringBuilder sb72 = new TextStringBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow TextStringBuilder sb73 = new TextStringBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow TextStringBuilder sb74 = new TextStringBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow + + // Tests for fluent methods (those returning `this`): + + TextStringBuilder fluentTest = new TextStringBuilder(); + sink(fluentTest.append("Harmless").append(taint()).append("Also harmless").toString()); // $hasTaintFlow + + TextStringBuilder fluentBackflowTest = new TextStringBuilder(); + fluentBackflowTest.append("Harmless").append(taint()).append("Also harmless"); + sink(fluentBackflowTest.toString()); // $hasTaintFlow + + // Test the case where the fluent method contributing taint is at the end of a statement: + TextStringBuilder fluentBackflowTest2 = new TextStringBuilder(); + fluentBackflowTest2.append("Harmless").append(taint()); + sink(fluentBackflowTest2.toString()); // $hasTaintFlow + + // Test all fluent methods are passing taint through to their result: + TextStringBuilder fluentAllMethodsTest = new TextStringBuilder(taint()); + sink(fluentAllMethodsTest // $hasTaintFlow + .append("text") + .appendAll("text") + .appendFixedWidthPadLeft("text", 4, ' ') + .appendFixedWidthPadRight("text", 4, ' ') + .appendln("text") + .appendNewLine() + .appendNull() + .appendPadding(0, ' ') + .appendSeparator(',') + .appendWithSeparators(new String[] { }, ",") + .delete(0, 0) + .deleteAll(' ') + .deleteCharAt(0) + .deleteFirst("delme") + .ensureCapacity(100) + .insert(1, "insertme") + .minimizeCapacity() + .replace(0, 0, "replacement") + .replaceAll("find", "replace") + .replaceFirst("find", "replace") + .reverse() + .setCharAt(0, 'a') + .setLength(500) + .setNewLineText("newline") + .setNullText("NULL") + .trim()); + + // Test all fluent methods are passing taint back to their qualifier: + TextStringBuilder fluentAllMethodsTest2 = new TextStringBuilder(); + fluentAllMethodsTest2 + .append("text") + .appendAll("text") + .appendFixedWidthPadLeft("text", 4, ' ') + .appendFixedWidthPadRight("text", 4, ' ') + .appendln("text") + .appendNewLine() + .appendNull() + .appendPadding(0, ' ') + .appendSeparator(',') + .appendWithSeparators(new String[] { }, ",") + .delete(0, 0) + .deleteAll(' ') + .deleteCharAt(0) + .deleteFirst("delme") + .ensureCapacity(100) + .insert(1, "insertme") + .minimizeCapacity() + .replace(0, 0, "replacement") + .replaceAll("find", "replace") + .replaceFirst("find", "replace") + .reverse() + .setCharAt(0, 'a') + .setLength(500) + .setNewLineText("newline") + .setNullText("NULL") + .trim() + .append(taint()); + sink(fluentAllMethodsTest2); // $hasTaintFlow } } \ No newline at end of file From 42b63a61ae82b19a7e61c86bebfe27365d35bf79 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 11 Mar 2021 18:34:11 +0000 Subject: [PATCH 003/272] Add change note --- java/change-notes/2021-03-11-commons-strbuilder.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 java/change-notes/2021-03-11-commons-strbuilder.md diff --git a/java/change-notes/2021-03-11-commons-strbuilder.md b/java/change-notes/2021-03-11-commons-strbuilder.md new file mode 100644 index 00000000000..ce8f647ab0f --- /dev/null +++ b/java/change-notes/2021-03-11-commons-strbuilder.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added support for the Apache Commons Lang and Commons Text StrBuilder class, and its successor TextStringBuilder. From 6589460357229d5340539ae8e9b4442460a70902 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 16 Feb 2021 12:21:57 +0000 Subject: [PATCH 004/272] Add models for Commons ToStringBuilder These don't include support for reflectionToString yet, which is coming up in a subsequent PR. --- .../code/java/frameworks/apache/Lang.qll | 34 +++ .../ToStringBuilderTest.java | 37 +++ .../lang3/builder/ToStringBuilder.java | 275 ++++++++++++++++++ .../commons/lang3/builder/ToStringStyle.java | 102 +++++++ 4 files changed, 448 insertions(+) create mode 100644 java/ql/test/library-tests/frameworks/apache-commons-lang3/ToStringBuilderTest.java create mode 100644 java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringBuilder.java create mode 100644 java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringStyle.java diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index 670014e0f8f..935b6347ec5 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -637,3 +637,37 @@ private class ApacheObjectUtilsModel extends SummaryModelCsv { ] } } + +private class ApacheToStringBuilderModel extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + "org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument;ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument;ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument;ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument;ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument;ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument;ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument;Argument[-1];taint", + // The following are value-preserving steps for fluent methods: + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendAsObjectToString;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[-1];ReturnValue;value", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[-1];ReturnValue;value" + ] + } +} diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/ToStringBuilderTest.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/ToStringBuilderTest.java new file mode 100644 index 00000000000..ed2e4400dd7 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/ToStringBuilderTest.java @@ -0,0 +1,37 @@ +import org.apache.commons.lang3.builder.ToStringBuilder; + +class ToStringBuilderTest { + String taint() { return "tainted"; } + + void sink(Object o) {} + + void test() throws Exception { + + ToStringBuilder sb1 = new ToStringBuilder(null); sb1.append((Object)taint()); sink(sb1.toString()); // $hasTaintFlow + ToStringBuilder sb2 = new ToStringBuilder(null); sb2.append(new Object[] { taint() }); sink(sb2.toString()); // $hasTaintFlow + ToStringBuilder sb3 = new ToStringBuilder(null); sb3.append(taint(), true); sink(sb3.toString()); // $hasTaintFlow + ToStringBuilder sb4 = new ToStringBuilder(null); sb4.append("fieldname", taint()); sink(sb4.toString()); // $hasTaintFlow + ToStringBuilder sb5 = new ToStringBuilder(null); sb5.append("fieldname", new Object[] { taint() }); sink(sb5.toString()); // $hasTaintFlow + ToStringBuilder sb6 = new ToStringBuilder(null); sb6.append("fieldname", new Object[] { taint() }, true); sink(sb6.toString()); // $hasTaintFlow + // GOOD: this appends an Object using the Object.toString style, which does not expose fields or String content. + ToStringBuilder sb7 = new ToStringBuilder(null); sb7.appendAsObjectToString(taint()); sink(sb7.toString()); + ToStringBuilder sb8 = new ToStringBuilder(null); sb8.appendSuper(taint()); sink(sb8.toString()); // $hasTaintFlow + ToStringBuilder sb9 = new ToStringBuilder(null); sb9.appendToString(taint()); sink(sb9.toString()); // $hasTaintFlow + ToStringBuilder sb10 = new ToStringBuilder(null); sb10.append((Object)taint()); sink(sb10.build()); // $hasTaintFlow + ToStringBuilder sb11 = new ToStringBuilder(null); sb11.append((Object)taint()); sink(sb11.getStringBuffer().toString()); // $hasTaintFlow + + // Test fluent methods: + ToStringBuilder fluentTest = new ToStringBuilder(null); + sink(fluentTest.append("Harmless").append(taint()).append("Also harmless").toString()); // $hasTaintFlow + + ToStringBuilder fluentBackflowTest = new ToStringBuilder(null); + fluentBackflowTest.append("Harmless").append(taint()).append("Also harmless"); + sink(fluentBackflowTest.toString()); // $hasTaintFlow + + // Test the case where the fluent method contributing taint is at the end of a statement: + ToStringBuilder fluentBackflowTest2 = new ToStringBuilder(null); + fluentBackflowTest2.append("Harmless").append(taint()); + sink(fluentBackflowTest2.toString()); // $hasTaintFlow + + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringBuilder.java b/java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringBuilder.java new file mode 100644 index 00000000000..886d59637f0 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringBuilder.java @@ -0,0 +1,275 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.lang3.builder; + + +public class ToStringBuilder implements Builder { + public static ToStringStyle getDefaultStyle() { + return null; + } + + public static void setDefaultStyle(final ToStringStyle style) { + } + + public static String reflectionToString(final Object object) { + return null; + } + + public static String reflectionToString(final Object object, final ToStringStyle style) { + return null; + } + + public static String reflectionToString(final Object object, final ToStringStyle style, final boolean outputTransients) { + return null; + } + + public static String reflectionToString( + final T object, + final ToStringStyle style, + final boolean outputTransients, + final Class reflectUpToClass) { + return null; + } + + public ToStringBuilder(final Object object) { + } + + public ToStringBuilder(final Object object, final ToStringStyle style) { + } + + public ToStringBuilder(final Object object, ToStringStyle style, StringBuffer buffer) { + } + + public ToStringBuilder append(final boolean value) { + return null; + } + + public ToStringBuilder append(final boolean[] array) { + return null; + } + + public ToStringBuilder append(final byte value) { + return null; + } + + public ToStringBuilder append(final byte[] array) { + return null; + } + + public ToStringBuilder append(final char value) { + return null; + } + + public ToStringBuilder append(final char[] array) { + return null; + } + + public ToStringBuilder append(final double value) { + return null; + } + + public ToStringBuilder append(final double[] array) { + return null; + } + + public ToStringBuilder append(final float value) { + return null; + } + + public ToStringBuilder append(final float[] array) { + return null; + } + + public ToStringBuilder append(final int value) { + return null; + } + + public ToStringBuilder append(final int[] array) { + return null; + } + + public ToStringBuilder append(final long value) { + return null; + } + + public ToStringBuilder append(final long[] array) { + return null; + } + + public ToStringBuilder append(final Object obj) { + return null; + } + + public ToStringBuilder append(final Object[] array) { + return null; + } + + public ToStringBuilder append(final short value) { + return null; + } + + public ToStringBuilder append(final short[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final boolean value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final boolean[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final boolean[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final byte value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final byte[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final byte[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final char value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final char[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final char[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final double value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final double[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final double[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final float value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final float[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final float[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final int value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final int[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final int[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final long value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final long[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final long[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final Object obj) { + return null; + } + + public ToStringBuilder append(final String fieldName, final Object obj, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final Object[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final Object[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder append(final String fieldName, final short value) { + return null; + } + + public ToStringBuilder append(final String fieldName, final short[] array) { + return null; + } + + public ToStringBuilder append(final String fieldName, final short[] array, final boolean fullDetail) { + return null; + } + + public ToStringBuilder appendAsObjectToString(final Object srcObject) { + return null; + } + + public ToStringBuilder appendSuper(final String superToString) { + return null; + } + + public ToStringBuilder appendToString(final String toString) { + return null; + } + + public Object getObject() { + return null; + } + + public StringBuffer getStringBuffer() { + return null; + } + + public ToStringStyle getStyle() { + return null; + } + + @Override + public String toString() { + return null; + } + + @Override + public String build() { + return null; + } + +} diff --git a/java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringStyle.java b/java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringStyle.java new file mode 100644 index 00000000000..eef4db08804 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-lang3-3.7/org/apache/commons/lang3/builder/ToStringStyle.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.lang3.builder; + +import java.io.Serializable; + +public abstract class ToStringStyle implements Serializable { + public static final ToStringStyle DEFAULT_STYLE = null; + + public static final ToStringStyle MULTI_LINE_STYLE = null; + + public static final ToStringStyle NO_FIELD_NAMES_STYLE = null; + + public static final ToStringStyle SHORT_PREFIX_STYLE = null; + + public static final ToStringStyle SIMPLE_STYLE = null; + + public static final ToStringStyle NO_CLASS_NAME_STYLE = null; + + public static final ToStringStyle JSON_STYLE = null; + + public void appendSuper(final StringBuffer buffer, final String superToString) { + } + + public void appendToString(final StringBuffer buffer, final String toString) { + } + + public void appendStart(final StringBuffer buffer, final Object object) { + } + + public void appendEnd(final StringBuffer buffer, final Object object) { + } + + public void append(final StringBuffer buffer, final String fieldName, final Object value, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final long value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final int value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final short value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final byte value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final char value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final double value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final float value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final boolean value) { + } + + public void append(final StringBuffer buffer, final String fieldName, final Object[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final long[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final int[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final short[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final byte[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final char[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final double[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final float[] array, final Boolean fullDetail) { + } + + public void append(final StringBuffer buffer, final String fieldName, final boolean[] array, final Boolean fullDetail) { + } + +} From fce1d6122fa1ba2372d53595f76b026751e05643 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Mar 2021 09:09:16 +0000 Subject: [PATCH 005/272] Add change note --- java/change-notes/2021-03-18-commons-tostring-builder.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 java/change-notes/2021-03-18-commons-tostring-builder.md diff --git a/java/change-notes/2021-03-18-commons-tostring-builder.md b/java/change-notes/2021-03-18-commons-tostring-builder.md new file mode 100644 index 00000000000..41ccfb95237 --- /dev/null +++ b/java/change-notes/2021-03-18-commons-tostring-builder.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added models for Apache Commons Lang's `ToStringBuilder` class. This may lead to more results from any data-flow query where ToStringBuilder operations fall between the relevant untrusted source and vulnerable sink. From 874733a61b25d78af4e474aeb045f51ad7a0aa5f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 21 Apr 2021 15:53:55 +0100 Subject: [PATCH 006/272] Argument -> specific Argument indices --- .../code/java/frameworks/apache/Lang.qll | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index 935b6347ec5..b87c7044216 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -643,26 +643,26 @@ private class ApacheToStringBuilderModel extends SummaryModelCsv { row = [ "org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument;ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument;Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument;ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument;Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument;ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument;ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument;ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument;Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument;ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument;Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];Argument[-1];taint", // The following are value-preserving steps for fluent methods: "org.apache.commons.lang3.builder;ToStringBuilder;false;append;;;Argument[-1];ReturnValue;value", "org.apache.commons.lang3.builder;ToStringBuilder;false;appendAsObjectToString;;;Argument[-1];ReturnValue;value", From 2c95b7539f8eeaffcee400a2ab8d730a1abbe312 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 21 Apr 2021 15:57:09 +0100 Subject: [PATCH 007/272] Remove now-redundant steps --- .../src/semmle/code/java/frameworks/apache/Lang.qll | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index b87c7044216..7ff539ec041 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -643,25 +643,15 @@ private class ApacheToStringBuilderModel extends SummaryModelCsv { row = [ "org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1];ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0..1];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];Argument[-1];taint", // The following are value-preserving steps for fluent methods: "org.apache.commons.lang3.builder;ToStringBuilder;false;append;;;Argument[-1];ReturnValue;value", From 76091f0f8db56886b9dd204b5a032132f0810605 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 21 Apr 2021 15:58:41 +0100 Subject: [PATCH 008/272] Use ArrayElement accessor where needed --- java/ql/src/semmle/code/java/frameworks/apache/Lang.qll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index 7ff539ec041..516b3c5588e 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -644,11 +644,13 @@ private class ApacheToStringBuilderModel extends SummaryModelCsv { [ "org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;ArrayElement of Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];Argument[-1];taint", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];Argument[-1];taint", From 53e04d0d96dd0038a8d2f47d2a098bd79c2095c0 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 30 Apr 2021 17:53:43 +0200 Subject: [PATCH 009/272] Refactor to CSV sink model --- .../Security/CWE/CWE-094/JexlInjection.ql | 19 ++ .../Security/CWE/CWE-094/JexlInjectionLib.qll | 178 +++++++++++------- 2 files changed, 127 insertions(+), 70 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql index 2a23dd7368d..8b5e0d8eea1 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql @@ -13,6 +13,25 @@ import java import JexlInjectionLib import DataFlow::PathGraph +import FlowUtils + +/** + * A taint-tracking configuration for unsafe user input + * that is used to construct and evaluate a JEXL expression. + * It supports both JEXL 2 and 3. + */ +class JexlInjectionConfig extends TaintTracking::Configuration { + JexlInjectionConfig() { this = "JexlInjectionConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } + + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + any(JexlInjectionAdditionalTaintStep c).step(node1, node2) or + hasGetterFlow(node1, node2) + } +} from DataFlow::PathNode source, DataFlow::PathNode sink, JexlInjectionConfig conf where conf.hasFlowPath(source, sink) diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll index 89d7cb496a4..dfe3a793ef3 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll @@ -1,89 +1,127 @@ import java -import FlowUtils -import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.TaintTracking - -/** - * A taint-tracking configuration for unsafe user input - * that is used to construct and evaluate a JEXL expression. - * It supports both JEXL 2 and 3. - */ -class JexlInjectionConfig extends TaintTracking::Configuration { - JexlInjectionConfig() { this = "JexlInjectionConfig" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } - - override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - any(TaintPropagatingJexlMethodCall c).taintFlow(fromNode, toNode) or - hasGetterFlow(fromNode, toNode) - } -} +private import semmle.code.java.dataflow.ExternalFlow /** * A sink for Expresssion Language injection vulnerabilities via Jexl, * i.e. method calls that run evaluation of a JEXL expression. - * - * Creating a `Callable` from a tainted JEXL expression or script is considered as a sink - * although the tainted expression is not executed at this point. - * Here we assume that it will get executed at some point, - * maybe stored in an object field and then reached by a different flow. */ -private class JexlEvaluationSink extends DataFlow::ExprNode { - JexlEvaluationSink() { - exists(MethodAccess ma, Method m, Expr taintFrom | - ma.getMethod() = m and taintFrom = this.asExpr() - | - m instanceof DirectJexlEvaluationMethod and ma.getQualifier() = taintFrom - or - m instanceof CreateJexlCallableMethod and ma.getQualifier() = taintFrom - or - m instanceof JexlEngineGetSetPropertyMethod and - taintFrom.getType() instanceof TypeString and - ma.getAnArgument() = taintFrom - ) +abstract class JexlEvaluationSink extends DataFlow::ExprNode { } + +/** Default sink for JXEL injection vulnerabilities. */ +private class DefaultJexlEvaluationSink extends JexlEvaluationSink { + DefaultJexlEvaluationSink() { sinkNode(this, "jexl") } +} + +private class DefaultJexlInjectionSinkModel extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // JEXL2 + "org.apache.commons.jexl2;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl", + "org.apache.commons.jexl2;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl", + "org.apache.commons.jexl2;JexlEngine;false;setProperty;(JexlContext,Object,String,Object);;Argument[2];jexl", + "org.apache.commons.jexl2;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl", + "org.apache.commons.jexl2;Expression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl2;Expression;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JexlExpression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JexlExpression;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl2;Script;false;execute;;;Argument[-1];jexl", + "org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl", + "org.apache.commons.jexl2;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl", + "org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl", + // JEXL3 + "org.apache.commons.jexl3;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl", + "org.apache.commons.jexl3;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl", + "org.apache.commons.jexl3;JexlEngine;false;setProperty;(JexlContext,Object,String);;Argument[2];jexl", + "org.apache.commons.jexl3;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl", + "org.apache.commons.jexl3;Expression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl3;Expression;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JexlExpression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JexlExpression;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl3;Script;false;execute;;;Argument[-1];jexl", + "org.apache.commons.jexl3;Script;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JexlScript;false;execute;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl", + "org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl3;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl", + "org.apache.commons.jexl3;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl", + "org.apache.commons.jexl3;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl" + ] } } /** - * Defines method calls that propagate tainted data via one of the methods - * from JEXL library. + * A unit class for adding additional taint steps. + * + * Extend this class to add additional taint steps that should apply to the `JexlInjectionFlowConfig`. */ -private class TaintPropagatingJexlMethodCall extends MethodAccess { - Expr taintFromExpr; - - TaintPropagatingJexlMethodCall() { - exists(Method m, RefType taintType | - this.getMethod() = m and - taintType = taintFromExpr.getType() - | - isUnsafeEngine(this.getQualifier()) and - ( - m instanceof CreateJexlScriptMethod and - taintFromExpr = this.getArgument(0) and - taintType instanceof TypeString - or - m instanceof CreateJexlExpressionMethod and - taintFromExpr = this.getAnArgument() and - taintType instanceof TypeString - or - m instanceof CreateJexlTemplateMethod and - (taintType instanceof TypeString or taintType instanceof Reader) and - taintFromExpr = this.getArgument([0, 1]) - ) - ) - } - +abstract class JexlInjectionAdditionalTaintStep extends Unit { /** - * Holds if `fromNode` to `toNode` is a dataflow step that propagates - * tainted data. + * Holds if the step from `node1` to `node2` should be considered a taint + * step for the `JexlInjectionConfig` configuration. */ - predicate taintFlow(DataFlow::Node fromNode, DataFlow::Node toNode) { - fromNode.asExpr() = taintFromExpr and toNode.asExpr() = this + abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); +} + +/** A set of additional taint steps to consider when taint tracking JXEL related data flows. */ +private class DefaultJexlInjectionAdditionalTaintStep extends JexlInjectionAdditionalTaintStep { + override predicate step(DataFlow::Node node1, DataFlow::Node node2) { + createJexlScriptStep(node1, node2) or + createJexlExpressionStep(node1, node2) or + createJexlTemplateStep(node1, node2) } } +/** + * Holds if `n1` to `n2` is a dataflow step that creates a JEXL script using an unsafe engine + * i.e. `tainted.createScript(jexlExpr)`. + */ +private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { + exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | + isUnsafeEngine(ma.getQualifier()) and + m instanceof CreateJexlScriptMethod and + n1.asExpr() = ma.getArgument(0) and + n1.asExpr().getType() instanceof TypeString + ) +} + +/** + * Holds if `n1` to `n2` is a dataflow step that creates a JEXL expression using an unsafe engine + * i.e. `tainted.createExpression(jexlExpr)`. + */ +private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) { + exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | + isUnsafeEngine(ma.getQualifier()) and + m instanceof CreateJexlExpressionMethod and + n1.asExpr() = ma.getAnArgument() and + n1.asExpr().getType() instanceof TypeString + ) +} + +/** + * Holds if `n1` to `n2` is a dataflow step that creates a JEXL template using an unsafe engine + * i.e. `tainted.createTemplate(jexlExpr)`. + */ +private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { + exists(MethodAccess ma, Method m, RefType taintType | + m = ma.getMethod() and n2.asExpr() = ma and taintType = n1.asExpr().getType() + | + isUnsafeEngine(ma.getQualifier()) and + m instanceof CreateJexlTemplateMethod and + n1.asExpr() = ma.getArgument([0, 1]) and + (taintType instanceof TypeString or taintType instanceof Reader) + ) +} + /** * Holds if `expr` is a JEXL engine that is not configured with a sandbox. */ @@ -92,7 +130,7 @@ private predicate isUnsafeEngine(Expr expr) { } /** - * A configuration for a tracking sandboxed JEXL engines. + * A configuration for tracking sandboxed JEXL engines. */ private class SandboxedJexlFlowConfig extends DataFlow2::Configuration { SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" } From 38e052482c4b1017396962f29705d38f1c8854ae Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 3 May 2021 12:44:53 +0200 Subject: [PATCH 010/272] More csv sinks and sources --- .../Security/CWE/CWE-094/JexlInjectionLib.qll | 140 +++++------------- .../query-tests/security/CWE-094/options | 2 +- .../apache/commons/jexl2/JexlArithmetic.java | 5 + .../org/apache/commons/jexl2/JexlEngine.java | 16 +- .../org/apache/commons/logging/Log.java | 5 + 5 files changed, 54 insertions(+), 114 deletions(-) create mode 100644 java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlArithmetic.java create mode 100644 java/ql/test/stubs/apache-commons-logging-1.2/org/apache/commons/logging/Log.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll index dfe3a793ef3..811d9877112 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll @@ -30,9 +30,6 @@ private class DefaultJexlInjectionSinkModel extends SinkModelCsv { "org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl", "org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl", "org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl", - "org.apache.commons.jexl2;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl", - "org.apache.commons.jexl2;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl", - "org.apache.commons.jexl2;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl", "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl", "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl", "org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl", @@ -51,10 +48,7 @@ private class DefaultJexlInjectionSinkModel extends SinkModelCsv { "org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl", "org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl", "org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl", - "org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl", - "org.apache.commons.jexl3;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl", - "org.apache.commons.jexl3;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl", - "org.apache.commons.jexl3;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl" + "org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl" ] } } @@ -135,48 +129,50 @@ private predicate isUnsafeEngine(Expr expr) { private class SandboxedJexlFlowConfig extends DataFlow2::Configuration { SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" } - override predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource } + override predicate isSource(DataFlow::Node node) { sourceNode(node, "sandboxed-jexl") } - override predicate isSink(DataFlow::Node node) { - exists(MethodAccess ma, Method m | ma.getMethod() = m | - ( - m instanceof CreateJexlScriptMethod or - m instanceof CreateJexlExpressionMethod or - m instanceof CreateJexlTemplateMethod - ) and - ma.getQualifier() = node.asExpr() - ) - } + override predicate isSink(DataFlow::Node node) { sinkNode(node, "sandboxed-jexl") } override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - createsJexlEngine(fromNode, toNode) + createJexlEngineStep(fromNode, toNode) } } -/** - * Defines a data flow source for JEXL engines configured with a sandbox. - */ -private class SandboxedJexlSource extends DataFlow::ExprNode { - SandboxedJexlSource() { - exists(MethodAccess ma, Method m | m = ma.getMethod() | - m.getDeclaringType() instanceof JexlBuilder and - m.hasName(["uberspect", "sandbox"]) and - m.getReturnType() instanceof JexlBuilder and - this.asExpr() = [ma, ma.getQualifier()] - ) - or - exists(ConstructorCall cc | - cc.getConstructedType() instanceof JexlEngine and - cc.getArgument(0).getType() instanceof JexlUberspect and - cc = this.asExpr() - ) +private class SandoboxedJexlSourceModel extends SourceModelCsv { + override predicate row(string row) { + row = + [ + // JEXL2 + "org.apache.commons.jexl2;JexlEngine;false;JexlEngine;(Uberspect,JexlArithmetic,Map,Log);;ReturnValue;sandboxed-jexl", + // JEXL3 + "org.apache.commons.jexl3;JexlBuilder;false;uberspect;(JexlUberspect);;ReturnValue;sandboxed-jexl", + "org.apache.commons.jexl3;JexlBuilder;false;sandbox;(JexlSandbox);;ReturnValue;sandboxed-jexl" + ] + } +} + +private class SandoboxedJexlSinkModel extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // JEXL2 + "org.apache.commons.jexl2;JexlEngine;false;createScript;;;Argument[-1];sandboxed-jexl", + "org.apache.commons.jexl2;JexlEngine;false;createExpression;;;Argument[-1];sandboxed-jexl", + "org.apache.commons.jexl2;UnifiedJEXL;false;parse;;;Argument[-1];sandboxed-jexl", + "org.apache.commons.jexl2;UnifiedJEXL;false;createTemplate;;;Argument[-1];sandboxed-jexl", + // JEXL3 + "org.apache.commons.jexl3;JexlEngine;false;createScript;;;Argument[-1];sandboxed-jexl", + "org.apache.commons.jexl3;JexlEngine;false;createExpression;;;Argument[-1];sandboxed-jexl", + "org.apache.commons.jexl3;JxltEngine;false;createExpression;;;Argument[-1];sandboxed-jexl", + "org.apache.commons.jexl3;JxltEngine;false;createTemplate;;;Argument[-1];sandboxed-jexl" + ] } } /** * Holds if `fromNode` to `toNode` is a dataflow step that creates one of the JEXL engines. */ -private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNode) { +private predicate createJexlEngineStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodAccess ma, Method m | m = ma.getMethod() | (m.getDeclaringType() instanceof JexlBuilder or m.getDeclaringType() instanceof JexlEngine) and m.hasName(["create", "createJxltEngine"]) and @@ -191,35 +187,6 @@ private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNo ) } -/** - * A methods in the `JexlEngine` class that gets or sets a property with a JEXL expression. - */ -private class JexlEngineGetSetPropertyMethod extends Method { - JexlEngineGetSetPropertyMethod() { - getDeclaringType() instanceof JexlEngine and - hasName(["getProperty", "setProperty"]) - } -} - -/** - * A method that triggers direct evaluation of JEXL expressions. - */ -private class DirectJexlEvaluationMethod extends Method { - DirectJexlEvaluationMethod() { - getDeclaringType() instanceof JexlExpression and hasName("evaluate") - or - getDeclaringType() instanceof JexlScript and hasName("execute") - or - getDeclaringType() instanceof JxltEngineExpression and hasName(["evaluate", "prepare"]) - or - getDeclaringType() instanceof JxltEngineTemplate and hasName("evaluate") - or - getDeclaringType() instanceof UnifiedJexlExpression and hasName(["evaluate", "prepare"]) - or - getDeclaringType() instanceof UnifiedJexlTemplate and hasName("evaluate") - } -} - /** * A method that creates a JEXL script. */ @@ -227,16 +194,6 @@ private class CreateJexlScriptMethod extends Method { CreateJexlScriptMethod() { getDeclaringType() instanceof JexlEngine and hasName("createScript") } } -/** - * A method that creates a `Callable` for a JEXL expression or script. - */ -private class CreateJexlCallableMethod extends Method { - CreateJexlCallableMethod() { - (getDeclaringType() instanceof JexlExpression or getDeclaringType() instanceof JexlScript) and - hasName("callable") - } -} - /** * A method that creates a JEXL template. */ @@ -263,14 +220,6 @@ private class JexlRefType extends RefType { JexlRefType() { getPackage().hasName(["org.apache.commons.jexl2", "org.apache.commons.jexl3"]) } } -private class JexlExpression extends JexlRefType { - JexlExpression() { hasName(["Expression", "JexlExpression"]) } -} - -private class JexlScript extends JexlRefType { - JexlScript() { hasName(["Script", "JexlScript"]) } -} - private class JexlBuilder extends JexlRefType { JexlBuilder() { hasName("JexlBuilder") } } @@ -287,29 +236,6 @@ private class UnifiedJexl extends JexlRefType { UnifiedJexl() { hasName("UnifiedJEXL") } } -private class JexlUberspect extends Interface { - JexlUberspect() { - hasQualifiedName("org.apache.commons.jexl2.introspection", "Uberspect") or - hasQualifiedName("org.apache.commons.jexl3.introspection", "JexlUberspect") - } -} - -private class JxltEngineExpression extends NestedType { - JxltEngineExpression() { getEnclosingType() instanceof JxltEngine and hasName("Expression") } -} - -private class JxltEngineTemplate extends NestedType { - JxltEngineTemplate() { getEnclosingType() instanceof JxltEngine and hasName("Template") } -} - -private class UnifiedJexlExpression extends NestedType { - UnifiedJexlExpression() { getEnclosingType() instanceof UnifiedJexl and hasName("Expression") } -} - -private class UnifiedJexlTemplate extends NestedType { - UnifiedJexlTemplate() { getEnclosingType() instanceof UnifiedJexl and hasName("Template") } -} - private class Reader extends RefType { Reader() { hasQualifiedName("java.io", "Reader") } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/options b/java/ql/test/experimental/query-tests/security/CWE-094/options index 18e3518fc97..4841ceb7488 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-094/options +++ b/java/ql/test/experimental/query-tests/security/CWE-094/options @@ -1,2 +1,2 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../../stubs/servlet-api-2.4 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/apache-commons-logging-1.2 diff --git a/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlArithmetic.java b/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlArithmetic.java new file mode 100644 index 00000000000..cff0dbeb54c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlArithmetic.java @@ -0,0 +1,5 @@ +package org.apache.commons.jexl2; + +public class JexlArithmetic { + +} diff --git a/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlEngine.java b/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlEngine.java index 38568b08ac0..b6cf38487f9 100644 --- a/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlEngine.java +++ b/java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlEngine.java @@ -2,12 +2,15 @@ package org.apache.commons.jexl2; import java.util.Map; import org.apache.commons.jexl2.introspection.*; +import org.apache.commons.logging.Log; public class JexlEngine { - public JexlEngine() {} + public JexlEngine() { + } - public JexlEngine(Uberspect uberspect, Object arithmetic, Map functions, Object log) {} + public JexlEngine(Uberspect uberspect, JexlArithmetic arithmetic, Map functions, Log log) { + } public Expression createExpression(String expression) { return null; @@ -41,9 +44,10 @@ public class JexlEngine { return null; } - public void setProperty(Object bean, String expr, Object value) {} + public void setProperty(Object bean, String expr, Object value) { + } + + public void setProperty(JexlContext context, Object bean, String expr, Object value) { + } - public void setProperty(JexlContext context, Object bean, String expr, Object value) {} - - } \ No newline at end of file diff --git a/java/ql/test/stubs/apache-commons-logging-1.2/org/apache/commons/logging/Log.java b/java/ql/test/stubs/apache-commons-logging-1.2/org/apache/commons/logging/Log.java new file mode 100644 index 00000000000..4c8ee14acc8 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-logging-1.2/org/apache/commons/logging/Log.java @@ -0,0 +1,5 @@ +package org.apache.commons.logging; + +public interface Log { + +} From 4bfd34b1fea100f4f08cd9c68065a44eeec0499f Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 3 May 2021 13:15:24 +0200 Subject: [PATCH 011/272] Moved from experimental --- .../Security/CWE/CWE-094/JexlInjection.qhelp | 0 .../Security/CWE/CWE-094/JexlInjection.ql | 7 ++++--- .../Security/CWE/CWE-094/JexlInjectionLib.qll | 0 .../query-tests/security/CWE-094/JexlInjection.qlref | 1 - .../test/experimental/query-tests/security/CWE-094/options | 2 +- .../query-tests/security/CWE-094/Jexl2Injection.java | 0 .../query-tests/security/CWE-094/Jexl3Injection.java | 0 .../query-tests/security/CWE-094/JexlInjection.expected | 0 .../test/query-tests/security/CWE-094/JexlInjection.qlref | 1 + .../query-tests/security/CWE-094/SandboxedJexl2.java | 0 .../query-tests/security/CWE-094/SandboxedJexl3.java | 0 java/ql/test/query-tests/security/CWE-094/options | 2 +- 12 files changed, 7 insertions(+), 6 deletions(-) rename java/ql/src/{experimental => }/Security/CWE/CWE-094/JexlInjection.qhelp (100%) rename java/ql/src/{experimental => }/Security/CWE/CWE-094/JexlInjection.ql (87%) rename java/ql/src/{experimental => }/Security/CWE/CWE-094/JexlInjectionLib.qll (100%) delete mode 100644 java/ql/test/experimental/query-tests/security/CWE-094/JexlInjection.qlref rename java/ql/test/{experimental => }/query-tests/security/CWE-094/Jexl2Injection.java (100%) rename java/ql/test/{experimental => }/query-tests/security/CWE-094/Jexl3Injection.java (100%) rename java/ql/test/{experimental => }/query-tests/security/CWE-094/JexlInjection.expected (100%) create mode 100644 java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref rename java/ql/test/{experimental => }/query-tests/security/CWE-094/SandboxedJexl2.java (100%) rename java/ql/test/{experimental => }/query-tests/security/CWE-094/SandboxedJexl3.java (100%) diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.qhelp b/java/ql/src/Security/CWE/CWE-094/JexlInjection.qhelp similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.qhelp rename to java/ql/src/Security/CWE/CWE-094/JexlInjection.qhelp diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql similarity index 87% rename from java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql rename to java/ql/src/Security/CWE/CWE-094/JexlInjection.ql index 8b5e0d8eea1..460fa4540ef 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql @@ -13,7 +13,8 @@ import java import JexlInjectionLib import DataFlow::PathGraph -import FlowUtils +import semmle.code.java.dataflow.FlowSources +//import FlowUtils /** * A taint-tracking configuration for unsafe user input @@ -28,8 +29,8 @@ class JexlInjectionConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - any(JexlInjectionAdditionalTaintStep c).step(node1, node2) or - hasGetterFlow(node1, node2) + any(JexlInjectionAdditionalTaintStep c).step(node1, node2) /*or + hasGetterFlow(node1, node2)*/ } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll b/java/ql/src/Security/CWE/CWE-094/JexlInjectionLib.qll similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll rename to java/ql/src/Security/CWE/CWE-094/JexlInjectionLib.qll diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/JexlInjection.qlref b/java/ql/test/experimental/query-tests/security/CWE-094/JexlInjection.qlref deleted file mode 100644 index 82ad87b1751..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-094/JexlInjection.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-094/JexlInjection.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/options b/java/ql/test/experimental/query-tests/security/CWE-094/options index 4841ceb7488..0104bad4f22 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-094/options +++ b/java/ql/test/experimental/query-tests/security/CWE-094/options @@ -1,2 +1,2 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/apache-commons-logging-1.2 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../../stubs/servlet-api-2.4 diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/Jexl2Injection.java b/java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-094/Jexl2Injection.java rename to java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/Jexl3Injection.java b/java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-094/Jexl3Injection.java rename to java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/JexlInjection.expected b/java/ql/test/query-tests/security/CWE-094/JexlInjection.expected similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-094/JexlInjection.expected rename to java/ql/test/query-tests/security/CWE-094/JexlInjection.expected diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref b/java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref new file mode 100644 index 00000000000..63f170df617 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-094/JexlInjection.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/SandboxedJexl2.java b/java/ql/test/query-tests/security/CWE-094/SandboxedJexl2.java similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-094/SandboxedJexl2.java rename to java/ql/test/query-tests/security/CWE-094/SandboxedJexl2.java diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/SandboxedJexl3.java b/java/ql/test/query-tests/security/CWE-094/SandboxedJexl3.java similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-094/SandboxedJexl3.java rename to java/ql/test/query-tests/security/CWE-094/SandboxedJexl3.java diff --git a/java/ql/test/query-tests/security/CWE-094/options b/java/ql/test/query-tests/security/CWE-094/options index 468d90aeabc..27fdb569cd8 100644 --- a/java/ql/test/query-tests/security/CWE-094/options +++ b/java/ql/test/query-tests/security/CWE-094/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2 From 4d5ec87de9b368fc57a21fea948316a10b21786b Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 3 May 2021 13:27:24 +0200 Subject: [PATCH 012/272] Use InlineTest --- .../src/Security/CWE/CWE-094/JexlInjection.ql | 6 +- .../code/java/security/JexlInjection.qll} | 0 .../security/CWE-094/Jexl2Injection.java | 21 +- .../security/CWE-094/Jexl3Injection.java | 26 ++- .../security/CWE-094/JexlInjection.expected | 199 ------------------ .../CWE-094/JexlInjectionTest.expected | 0 .../security/CWE-094/JexlInjectionTest.ql | 33 +++ .../security/CWE-094/SandboxedJexl2.java | 6 +- 8 files changed, 60 insertions(+), 231 deletions(-) rename java/ql/src/{Security/CWE/CWE-094/JexlInjectionLib.qll => semmle/code/java/security/JexlInjection.qll} (100%) delete mode 100644 java/ql/test/query-tests/security/CWE-094/JexlInjection.expected create mode 100644 java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected create mode 100644 java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql diff --git a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql index 460fa4540ef..80810378dce 100644 --- a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql @@ -11,10 +11,9 @@ */ import java -import JexlInjectionLib import DataFlow::PathGraph import semmle.code.java.dataflow.FlowSources -//import FlowUtils +import semmle.code.java.security.JexlInjection /** * A taint-tracking configuration for unsafe user input @@ -29,8 +28,7 @@ class JexlInjectionConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - any(JexlInjectionAdditionalTaintStep c).step(node1, node2) /*or - hasGetterFlow(node1, node2)*/ + any(JexlInjectionAdditionalTaintStep c).step(node1, node2) } } diff --git a/java/ql/src/Security/CWE/CWE-094/JexlInjectionLib.qll b/java/ql/src/semmle/code/java/security/JexlInjection.qll similarity index 100% rename from java/ql/src/Security/CWE/CWE-094/JexlInjectionLib.qll rename to java/ql/src/semmle/code/java/security/JexlInjection.qll diff --git a/java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java b/java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java index 438e9b036b6..d7ee659a4c8 100644 --- a/java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java +++ b/java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java @@ -11,22 +11,21 @@ public class Jexl2Injection { JexlEngine jexl = new JexlEngine(); Expression e = jexl.createExpression(jexlExpr); JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // $hasJexlInjection } private static void runJexlExpressionWithJexlInfo(String jexlExpr) { JexlEngine jexl = new JexlEngine(); - Expression e = jexl.createExpression( - jexlExpr, new DebugInfo("unknown", 0, 0)); + Expression e = jexl.createExpression(jexlExpr, new DebugInfo("unknown", 0, 0)); JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // $hasJexlInjection } private static void runJexlScript(String jexlExpr) { JexlEngine jexl = new JexlEngine(); Script script = jexl.createScript(jexlExpr); JexlContext jc = new MapContext(); - script.execute(jc); + script.execute(jc); // $hasJexlInjection } private static void runJexlScriptViaCallable(String jexlExpr) { @@ -35,7 +34,7 @@ public class Jexl2Injection { JexlContext jc = new MapContext(); try { - script.callable(jc).call(); + script.callable(jc).call(); // $hasJexlInjection } catch (Exception e) { throw new RuntimeException(e); } @@ -43,30 +42,30 @@ public class Jexl2Injection { private static void runJexlExpressionViaGetProperty(String jexlExpr) { JexlEngine jexl = new JexlEngine(); - jexl.getProperty(new Object(), jexlExpr); + jexl.getProperty(new Object(), jexlExpr); // $hasJexlInjection } private static void runJexlExpressionViaSetProperty(String jexlExpr) { JexlEngine jexl = new JexlEngine(); - jexl.setProperty(new Object(), jexlExpr, new Object()); + jexl.setProperty(new Object(), jexlExpr, new Object()); // $hasJexlInjection } private static void runJexlExpressionViaUnifiedJEXLParseAndEvaluate(String jexlExpr) { JexlEngine jexl = new JexlEngine(); UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl); - unifiedJEXL.parse(jexlExpr).evaluate(new MapContext()); + unifiedJEXL.parse(jexlExpr).evaluate(new MapContext()); // $hasJexlInjection } private static void runJexlExpressionViaUnifiedJEXLParseAndPrepare(String jexlExpr) { JexlEngine jexl = new JexlEngine(); UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl); - unifiedJEXL.parse(jexlExpr).prepare(new MapContext()); + unifiedJEXL.parse(jexlExpr).prepare(new MapContext()); // $hasJexlInjection } private static void runJexlExpressionViaUnifiedJEXLTemplateEvaluate(String jexlExpr) { JexlEngine jexl = new JexlEngine(); UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl); - unifiedJEXL.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter()); + unifiedJEXL.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter()); // $hasJexlInjection } private static void testWithSocket(Consumer action) throws Exception { diff --git a/java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java b/java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java index a23a8b35841..0300b8ffe3f 100644 --- a/java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java +++ b/java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java @@ -18,21 +18,21 @@ public class Jexl3Injection { JexlEngine jexl = new JexlBuilder().create(); JexlExpression e = jexl.createExpression(jexlExpr); JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // $hasJexlInjection } private static void runJexlExpressionWithJexlInfo(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); JexlExpression e = jexl.createExpression(new JexlInfo("unknown", 0, 0), jexlExpr); JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // $hasJexlInjection } private static void runJexlScript(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); JexlScript script = jexl.createScript(jexlExpr); JexlContext jc = new MapContext(); - script.execute(jc); + script.execute(jc); // $hasJexlInjection } private static void runJexlScriptViaCallable(String jexlExpr) { @@ -41,7 +41,7 @@ public class Jexl3Injection { JexlContext jc = new MapContext(); try { - script.callable(jc).call(); + script.callable(jc).call(); // $hasJexlInjection } catch (Exception e) { throw new RuntimeException(e); } @@ -49,30 +49,30 @@ public class Jexl3Injection { private static void runJexlExpressionViaGetProperty(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); - jexl.getProperty(new Object(), jexlExpr); + jexl.getProperty(new Object(), jexlExpr); // $hasJexlInjection } private static void runJexlExpressionViaSetProperty(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); - jexl.setProperty(new Object(), jexlExpr, new Object()); + jexl.setProperty(new Object(), jexlExpr, new Object()); // $hasJexlInjection } private static void runJexlExpressionViaJxltEngineExpressionEvaluate(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); JxltEngine jxlt = jexl.createJxltEngine(); - jxlt.createExpression(jexlExpr).evaluate(new MapContext()); + jxlt.createExpression(jexlExpr).evaluate(new MapContext()); // $hasJexlInjection } private static void runJexlExpressionViaJxltEngineExpressionPrepare(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); JxltEngine jxlt = jexl.createJxltEngine(); - jxlt.createExpression(jexlExpr).prepare(new MapContext()); + jxlt.createExpression(jexlExpr).prepare(new MapContext()); // $hasJexlInjection } private static void runJexlExpressionViaJxltEngineTemplateEvaluate(String jexlExpr) { JexlEngine jexl = new JexlBuilder().create(); JxltEngine jxlt = jexl.createJxltEngine(); - jxlt.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter()); + jxlt.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter()); // $hasJexlInjection } private static void runJexlExpressionViaCallable(String jexlExpr) { @@ -81,7 +81,7 @@ public class Jexl3Injection { JexlContext jc = new MapContext(); try { - e.callable(jc).call(); + e.callable(jc).call(); // $hasJexlInjection } catch (Exception ex) { throw new RuntimeException(ex); } @@ -141,16 +141,14 @@ public class Jexl3Injection { } @PostMapping("/request") - public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromPathVariable( - @PathVariable String expr) { + public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromPathVariable(@PathVariable String expr) { runJexlExpression(expr); return ResponseEntity.ok(HttpStatus.OK); } @PostMapping("/request") - public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromRequestBody( - @RequestBody Data data) { + public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromRequestBody(@RequestBody Data data) { String expr = data.getExpr(); runJexlExpression(expr); diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjection.expected b/java/ql/test/query-tests/security/CWE-094/JexlInjection.expected deleted file mode 100644 index f42f083578e..00000000000 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjection.expected +++ /dev/null @@ -1,199 +0,0 @@ -edges -| Jexl2Injection.java:10:43:10:57 | jexlExpr : String | Jexl2Injection.java:14:9:14:9 | e | -| Jexl2Injection.java:17:55:17:69 | jexlExpr : String | Jexl2Injection.java:22:9:22:9 | e | -| Jexl2Injection.java:25:39:25:53 | jexlExpr : String | Jexl2Injection.java:29:9:29:14 | script | -| Jexl2Injection.java:32:50:32:64 | jexlExpr : String | Jexl2Injection.java:38:13:38:18 | script | -| Jexl2Injection.java:44:57:44:71 | jexlExpr : String | Jexl2Injection.java:46:40:46:47 | jexlExpr | -| Jexl2Injection.java:49:57:49:71 | jexlExpr : String | Jexl2Injection.java:51:40:51:47 | jexlExpr | -| Jexl2Injection.java:54:73:54:87 | jexlExpr : String | Jexl2Injection.java:57:9:57:35 | parse(...) | -| Jexl2Injection.java:60:72:60:86 | jexlExpr : String | Jexl2Injection.java:63:9:63:35 | parse(...) | -| Jexl2Injection.java:66:73:66:87 | jexlExpr : String | Jexl2Injection.java:69:9:69:44 | createTemplate(...) | -| Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:76:54:76:58 | bytes [post update] : byte[] | -| Jexl2Injection.java:76:54:76:58 | bytes [post update] : byte[] | Jexl2Injection.java:78:31:78:38 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:86:24:86:56 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:90:24:90:68 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:94:24:94:52 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:98:24:98:63 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:102:24:102:70 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:106:24:106:70 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:110:24:110:86 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:114:24:114:85 | jexlExpr : String | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:118:24:118:86 | jexlExpr : String | -| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | Jexl2Injection.java:10:43:10:57 | jexlExpr : String | -| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | Jexl2Injection.java:86:24:86:56 | jexlExpr : String | -| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | Jexl2Injection.java:17:55:17:69 | jexlExpr : String | -| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | Jexl2Injection.java:90:24:90:68 | jexlExpr : String | -| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | Jexl2Injection.java:25:39:25:53 | jexlExpr : String | -| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | Jexl2Injection.java:94:24:94:52 | jexlExpr : String | -| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | Jexl2Injection.java:32:50:32:64 | jexlExpr : String | -| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | Jexl2Injection.java:98:24:98:63 | jexlExpr : String | -| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | Jexl2Injection.java:44:57:44:71 | jexlExpr : String | -| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | Jexl2Injection.java:102:24:102:70 | jexlExpr : String | -| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | Jexl2Injection.java:49:57:49:71 | jexlExpr : String | -| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | Jexl2Injection.java:106:24:106:70 | jexlExpr : String | -| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | Jexl2Injection.java:54:73:54:87 | jexlExpr : String | -| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | Jexl2Injection.java:110:24:110:86 | jexlExpr : String | -| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | Jexl2Injection.java:60:72:60:86 | jexlExpr : String | -| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | Jexl2Injection.java:114:24:114:85 | jexlExpr : String | -| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | Jexl2Injection.java:66:73:66:87 | jexlExpr : String | -| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | Jexl2Injection.java:118:24:118:86 | jexlExpr : String | -| Jexl3Injection.java:17:43:17:57 | jexlExpr : String | Jexl3Injection.java:21:9:21:9 | e | -| Jexl3Injection.java:24:55:24:69 | jexlExpr : String | Jexl3Injection.java:28:9:28:9 | e | -| Jexl3Injection.java:31:39:31:53 | jexlExpr : String | Jexl3Injection.java:35:9:35:14 | script | -| Jexl3Injection.java:38:50:38:64 | jexlExpr : String | Jexl3Injection.java:44:13:44:18 | script | -| Jexl3Injection.java:50:57:50:71 | jexlExpr : String | Jexl3Injection.java:52:40:52:47 | jexlExpr | -| Jexl3Injection.java:55:57:55:71 | jexlExpr : String | Jexl3Injection.java:57:40:57:47 | jexlExpr | -| Jexl3Injection.java:60:74:60:88 | jexlExpr : String | Jexl3Injection.java:63:9:63:39 | createExpression(...) | -| Jexl3Injection.java:66:73:66:87 | jexlExpr : String | Jexl3Injection.java:69:9:69:39 | createExpression(...) | -| Jexl3Injection.java:72:72:72:86 | jexlExpr : String | Jexl3Injection.java:75:9:75:37 | createTemplate(...) | -| Jexl3Injection.java:78:54:78:68 | jexlExpr : String | Jexl3Injection.java:84:13:84:13 | e | -| Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:94:54:94:58 | bytes [post update] : byte[] | -| Jexl3Injection.java:94:54:94:58 | bytes [post update] : byte[] | Jexl3Injection.java:96:31:96:38 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:104:24:104:56 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:108:24:108:68 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:112:24:112:52 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:116:24:116:63 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:120:24:120:70 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:124:24:124:70 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:128:24:128:87 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:132:24:132:86 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:136:24:136:85 | jexlExpr : String | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:140:24:140:67 | jexlExpr : String | -| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String | -| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | Jexl3Injection.java:104:24:104:56 | jexlExpr : String | -| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | Jexl3Injection.java:24:55:24:69 | jexlExpr : String | -| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | Jexl3Injection.java:108:24:108:68 | jexlExpr : String | -| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | Jexl3Injection.java:31:39:31:53 | jexlExpr : String | -| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | Jexl3Injection.java:112:24:112:52 | jexlExpr : String | -| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | Jexl3Injection.java:38:50:38:64 | jexlExpr : String | -| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | Jexl3Injection.java:116:24:116:63 | jexlExpr : String | -| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | Jexl3Injection.java:50:57:50:71 | jexlExpr : String | -| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | Jexl3Injection.java:120:24:120:70 | jexlExpr : String | -| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | Jexl3Injection.java:55:57:55:71 | jexlExpr : String | -| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | Jexl3Injection.java:124:24:124:70 | jexlExpr : String | -| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | Jexl3Injection.java:60:74:60:88 | jexlExpr : String | -| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | Jexl3Injection.java:128:24:128:87 | jexlExpr : String | -| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | Jexl3Injection.java:66:73:66:87 | jexlExpr : String | -| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | Jexl3Injection.java:132:24:132:86 | jexlExpr : String | -| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | Jexl3Injection.java:72:72:72:86 | jexlExpr : String | -| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | Jexl3Injection.java:136:24:136:85 | jexlExpr : String | -| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | Jexl3Injection.java:78:54:78:68 | jexlExpr : String | -| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | Jexl3Injection.java:140:24:140:67 | jexlExpr : String | -| Jexl3Injection.java:145:13:145:37 | expr : String | Jexl3Injection.java:147:27:147:30 | expr : String | -| Jexl3Injection.java:147:27:147:30 | expr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String | -| Jexl3Injection.java:153:13:153:34 | data : Data | Jexl3Injection.java:156:27:156:30 | expr : String | -| Jexl3Injection.java:156:27:156:30 | expr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String | -| Jexl3Injection.java:163:13:163:52 | customRequest : CustomRequest | Jexl3Injection.java:166:27:166:30 | expr : String | -| Jexl3Injection.java:166:27:166:30 | expr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String | -nodes -| Jexl2Injection.java:10:43:10:57 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:14:9:14:9 | e | semmle.label | e | -| Jexl2Injection.java:17:55:17:69 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:22:9:22:9 | e | semmle.label | e | -| Jexl2Injection.java:25:39:25:53 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:29:9:29:14 | script | semmle.label | script | -| Jexl2Injection.java:32:50:32:64 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:38:13:38:18 | script | semmle.label | script | -| Jexl2Injection.java:44:57:44:71 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:46:40:46:47 | jexlExpr | semmle.label | jexlExpr | -| Jexl2Injection.java:49:57:49:71 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:51:40:51:47 | jexlExpr | semmle.label | jexlExpr | -| Jexl2Injection.java:54:73:54:87 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:57:9:57:35 | parse(...) | semmle.label | parse(...) | -| Jexl2Injection.java:60:72:60:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:63:9:63:35 | parse(...) | semmle.label | parse(...) | -| Jexl2Injection.java:66:73:66:87 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:69:9:69:44 | createTemplate(...) | semmle.label | createTemplate(...) | -| Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | -| Jexl2Injection.java:76:54:76:58 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] | -| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:17:43:17:57 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:21:9:21:9 | e | semmle.label | e | -| Jexl3Injection.java:24:55:24:69 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:28:9:28:9 | e | semmle.label | e | -| Jexl3Injection.java:31:39:31:53 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:35:9:35:14 | script | semmle.label | script | -| Jexl3Injection.java:38:50:38:64 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:44:13:44:18 | script | semmle.label | script | -| Jexl3Injection.java:50:57:50:71 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:52:40:52:47 | jexlExpr | semmle.label | jexlExpr | -| Jexl3Injection.java:55:57:55:71 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:57:40:57:47 | jexlExpr | semmle.label | jexlExpr | -| Jexl3Injection.java:60:74:60:88 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:63:9:63:39 | createExpression(...) | semmle.label | createExpression(...) | -| Jexl3Injection.java:66:73:66:87 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:69:9:69:39 | createExpression(...) | semmle.label | createExpression(...) | -| Jexl3Injection.java:72:72:72:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:75:9:75:37 | createTemplate(...) | semmle.label | createTemplate(...) | -| Jexl3Injection.java:78:54:78:68 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:84:13:84:13 | e | semmle.label | e | -| Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | -| Jexl3Injection.java:94:54:94:58 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] | -| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | semmle.label | jexlExpr : String | -| Jexl3Injection.java:145:13:145:37 | expr : String | semmle.label | expr : String | -| Jexl3Injection.java:147:27:147:30 | expr : String | semmle.label | expr : String | -| Jexl3Injection.java:153:13:153:34 | data : Data | semmle.label | data : Data | -| Jexl3Injection.java:156:27:156:30 | expr : String | semmle.label | expr : String | -| Jexl3Injection.java:163:13:163:52 | customRequest : CustomRequest | semmle.label | customRequest : CustomRequest | -| Jexl3Injection.java:166:27:166:30 | expr : String | semmle.label | expr : String | -#select -| Jexl2Injection.java:14:9:14:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:14:9:14:9 | e | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:22:9:22:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:22:9:22:9 | e | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:29:9:29:14 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:29:9:29:14 | script | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:38:13:38:18 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:38:13:38:18 | script | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:46:40:46:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:46:40:46:47 | jexlExpr | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:51:40:51:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:51:40:51:47 | jexlExpr | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:57:9:57:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:57:9:57:35 | parse(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:63:9:63:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:63:9:63:35 | parse(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl2Injection.java:69:9:69:44 | createTemplate(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:69:9:69:44 | createTemplate(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:145:13:145:37 | expr : String | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:145:13:145:37 | expr | this user input | -| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:153:13:153:34 | data : Data | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:153:13:153:34 | data | this user input | -| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:163:13:163:52 | customRequest : CustomRequest | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:163:13:163:52 | customRequest | this user input | -| Jexl3Injection.java:28:9:28:9 | e | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:28:9:28:9 | e | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:35:9:35:14 | script | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:35:9:35:14 | script | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:44:13:44:18 | script | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:44:13:44:18 | script | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:52:40:52:47 | jexlExpr | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:52:40:52:47 | jexlExpr | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:57:40:57:47 | jexlExpr | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:57:40:57:47 | jexlExpr | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:63:9:63:39 | createExpression(...) | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:63:9:63:39 | createExpression(...) | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:69:9:69:39 | createExpression(...) | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:69:9:69:39 | createExpression(...) | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:75:9:75:37 | createTemplate(...) | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:75:9:75:37 | createTemplate(...) | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | -| Jexl3Injection.java:84:13:84:13 | e | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:84:13:84:13 | e | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input | diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql new file mode 100644 index 00000000000..e7c713213b0 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql @@ -0,0 +1,33 @@ +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSteps +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.JexlInjection +import TestUtilities.InlineExpectationsTest + +class Conf extends TaintTracking::Configuration { + Conf() { this = "qltest:cwe:jexl-injection" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } + + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + any(JexlInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +class JexlInjectionTest extends InlineExpectationsTest { + JexlInjectionTest() { this = "HasJexlInjectionTest" } + + override string getARelevantTag() { result = "hasJexlInjection" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasJexlInjection" and + exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-094/SandboxedJexl2.java b/java/ql/test/query-tests/security/CWE-094/SandboxedJexl2.java index dd9b113ca0b..cbc955389b3 100644 --- a/java/ql/test/query-tests/security/CWE-094/SandboxedJexl2.java +++ b/java/ql/test/query-tests/security/CWE-094/SandboxedJexl2.java @@ -6,7 +6,7 @@ import java.net.Socket; import java.util.function.Consumer; public class SandboxedJexl2 { - + private static void runJexlExpressionWithSandbox(String jexlExpr) { Sandbox sandbox = new Sandbox(); sandbox.white(SandboxedJexl2.class.getCanonicalName()); @@ -14,7 +14,7 @@ public class SandboxedJexl2 { JexlEngine jexl = new JexlEngine(uberspect, null, null, null); Expression e = jexl.createExpression(jexlExpr); JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // Safe } private static void runJexlExpressionViaSandboxedUnifiedJexl(String jexlExpr) { @@ -23,7 +23,7 @@ public class SandboxedJexl2 { Uberspect uberspect = new SandboxUberspectImpl(null, sandbox); JexlEngine jexl = new JexlEngine(uberspect, null, null, null); UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl); - unifiedJEXL.parse(jexlExpr).evaluate(new MapContext()); + unifiedJEXL.parse(jexlExpr).evaluate(new MapContext()); // Safe } private static void simpleServer(Consumer action) throws Exception { From 745a6f6fb4a8c66daf615354f1f6de6c08f7a902 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 3 May 2021 17:43:33 +0200 Subject: [PATCH 013/272] Getters called on parameters propagate taint --- java/ql/src/Security/CWE/CWE-094/JexlInjection.ql | 2 +- .../semmle/code/java/dataflow/internal/TaintTrackingUtil.qll | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql index 80810378dce..c97de906aec 100644 --- a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql @@ -28,7 +28,7 @@ class JexlInjectionConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - any(JexlInjectionAdditionalTaintStep c).step(node1, node2) + any(JexlInjectionAdditionalTaintStep c).step(node1, node2) } } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index f9278ab815e..00d5b2bb093 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -14,6 +14,7 @@ private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.internal.DataFlowPrivate import semmle.code.java.dataflow.FlowSteps private import FlowSummaryImpl as FlowSummaryImpl +private import semmle.code.java.frameworks.JaxWS /** * Holds if taint can flow from `src` to `sink` in zero or more @@ -263,6 +264,8 @@ private predicate taintPreservingQualifierToMethod(Method m) { ) or m.(TaintPreservingCallable).returnsTaintFrom(-1) + or + exists(JaxRsResourceMethod resourceMethod | m.(GetterMethod).getDeclaringType() = resourceMethod.getAParameter().getType()) } private class StringReplaceMethod extends TaintPreservingCallable { From e68c6e66a5cb7fe70e61badb82206abeb3840007 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 3 May 2021 17:53:37 +0200 Subject: [PATCH 014/272] Remove qlref file --- java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref | 1 - 1 file changed, 1 deletion(-) delete mode 100644 java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref b/java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref deleted file mode 100644 index 63f170df617..00000000000 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjection.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-094/JexlInjection.ql \ No newline at end of file From 6b79ca6403b7b562b9a81389580f2394bfc706bd Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 4 May 2021 09:32:03 +0200 Subject: [PATCH 015/272] Fix warning --- java/ql/src/semmle/code/java/security/JexlInjection.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/semmle/code/java/security/JexlInjection.qll b/java/ql/src/semmle/code/java/security/JexlInjection.qll index 811d9877112..448c1f3cdb5 100644 --- a/java/ql/src/semmle/code/java/security/JexlInjection.qll +++ b/java/ql/src/semmle/code/java/security/JexlInjection.qll @@ -58,7 +58,7 @@ private class DefaultJexlInjectionSinkModel extends SinkModelCsv { * * Extend this class to add additional taint steps that should apply to the `JexlInjectionFlowConfig`. */ -abstract class JexlInjectionAdditionalTaintStep extends Unit { +class JexlInjectionAdditionalTaintStep extends Unit { /** * Holds if the step from `node1` to `node2` should be considered a taint * step for the `JexlInjectionConfig` configuration. From f79d2e06f90cadb82da04424f9456f5e6fb20a9a Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 4 May 2021 11:29:09 +0200 Subject: [PATCH 016/272] Fix failing checks --- java/change-notes/2021-05-04-jexl-injection-query.md | 2 ++ .../CWE/CWE-094/SaferJexlExpressionEvaluationWithSandbox.java | 0 .../SaferJexlExpressionEvaluationWithUberspectSandbox.java | 0 .../Security/CWE/CWE-094/UnsafeJexlExpressionEvaluation.java | 0 java/ql/src/semmle/code/java/security/JexlInjection.qll | 2 ++ 5 files changed, 4 insertions(+) create mode 100644 java/change-notes/2021-05-04-jexl-injection-query.md rename java/ql/src/{experimental => }/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithSandbox.java (100%) rename java/ql/src/{experimental => }/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithUberspectSandbox.java (100%) rename java/ql/src/{experimental => }/Security/CWE/CWE-094/UnsafeJexlExpressionEvaluation.java (100%) diff --git a/java/change-notes/2021-05-04-jexl-injection-query.md b/java/change-notes/2021-05-04-jexl-injection-query.md new file mode 100644 index 00000000000..4dad3c4a8f9 --- /dev/null +++ b/java/change-notes/2021-05-04-jexl-injection-query.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The query "Expression language injection (JEXL)" (`java/jexl-expression-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @artem-smotrakov](https://github.com/github/codeql/pull/4965) \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithSandbox.java b/java/ql/src/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithSandbox.java similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithSandbox.java rename to java/ql/src/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithSandbox.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithUberspectSandbox.java b/java/ql/src/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithUberspectSandbox.java similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithUberspectSandbox.java rename to java/ql/src/Security/CWE/CWE-094/SaferJexlExpressionEvaluationWithUberspectSandbox.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/UnsafeJexlExpressionEvaluation.java b/java/ql/src/Security/CWE/CWE-094/UnsafeJexlExpressionEvaluation.java similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-094/UnsafeJexlExpressionEvaluation.java rename to java/ql/src/Security/CWE/CWE-094/UnsafeJexlExpressionEvaluation.java diff --git a/java/ql/src/semmle/code/java/security/JexlInjection.qll b/java/ql/src/semmle/code/java/security/JexlInjection.qll index 448c1f3cdb5..d36fa0aad9b 100644 --- a/java/ql/src/semmle/code/java/security/JexlInjection.qll +++ b/java/ql/src/semmle/code/java/security/JexlInjection.qll @@ -1,3 +1,5 @@ +/** Provides classes to reason about Expression Langauge (JEXL) injection vulnerabilities. */ + import java import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.dataflow.ExternalFlow From 6e94dc5b85e6a0f245d06d956339a7842a6ba829 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 4 May 2021 13:15:20 +0200 Subject: [PATCH 017/272] Autoformatting --- .../semmle/code/java/dataflow/internal/TaintTrackingUtil.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 00d5b2bb093..262a3babc0b 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -265,7 +265,9 @@ private predicate taintPreservingQualifierToMethod(Method m) { or m.(TaintPreservingCallable).returnsTaintFrom(-1) or - exists(JaxRsResourceMethod resourceMethod | m.(GetterMethod).getDeclaringType() = resourceMethod.getAParameter().getType()) + exists(JaxRsResourceMethod resourceMethod | + m.(GetterMethod).getDeclaringType() = resourceMethod.getAParameter().getType() + ) } private class StringReplaceMethod extends TaintPreservingCallable { From 3ceb8bbcc6b5b43deae31a1c64331e86555eb601 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 5 May 2021 10:52:57 +0200 Subject: [PATCH 018/272] Python: Add cryptography test for EC Apparently, passing in the class (without instantiating it) is allowed --- python/ql/test/library-tests/frameworks/cryptography/test_ec.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/test/library-tests/frameworks/cryptography/test_ec.py b/python/ql/test/library-tests/frameworks/cryptography/test_ec.py index 0372d7e9dbf..96d60adb2fa 100644 --- a/python/ql/test/library-tests/frameworks/cryptography/test_ec.py +++ b/python/ql/test/library-tests/frameworks/cryptography/test_ec.py @@ -6,6 +6,7 @@ from cryptography.exceptions import InvalidSignature private_key = ec.generate_private_key(curve=ec.SECP384R1()) # $ PublicKeyGeneration keySize=384 +private_key = ec.generate_private_key(curve=ec.SECP384R1) # $ MISSING: PublicKeyGeneration keySize=384 public_key = private_key.public_key() HASH_ALGORITHM = hashes.SHA256() From 668bfd3a4163118fbffef379e613274e1d057f05 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 5 May 2021 12:29:55 +0200 Subject: [PATCH 019/272] Python: Support EC keygen without class-instance for cryptography I also added a new test to show off how what the origin ends up looking like... I think it looks ok --- .../semmle/python/frameworks/Cryptography.qll | 26 ++++++++++++++++--- .../cryptography/EcKeygenOrigin.expected | 5 ++++ .../frameworks/cryptography/EcKeygenOrigin.ql | 8 ++++++ .../cryptography/ec_keygen_origin.py | 20 ++++++++++++++ .../frameworks/cryptography/test_ec.py | 2 +- 5 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.expected create mode 100644 python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.ql create mode 100644 python/ql/test/library-tests/frameworks/cryptography/ec_keygen_origin.py diff --git a/python/ql/src/semmle/python/frameworks/Cryptography.qll b/python/ql/src/semmle/python/frameworks/Cryptography.qll index 266d41897d3..fe9177227bd 100644 --- a/python/ql/src/semmle/python/frameworks/Cryptography.qll +++ b/python/ql/src/semmle/python/frameworks/Cryptography.qll @@ -22,7 +22,7 @@ private module CryptographyModel { * Gets a predefined curve class from * `cryptography.hazmat.primitives.asymmetric.ec` with a specific key size (in bits). */ - private DataFlow::Node curveClassWithKeySize(int keySize) { + private API::Node predefinedCurveClass(int keySize) { exists(string curveName | result = API::moduleImport("cryptography") @@ -31,7 +31,6 @@ private module CryptographyModel { .getMember("asymmetric") .getMember("ec") .getMember(curveName) - .getAUse() | // obtained by manually looking at source code in // https://github.com/pyca/cryptography/blob/cba69f1922803f4f29a3fde01741890d88b8e217/src/cryptography/hazmat/primitives/asymmetric/ec.py#L208-L300 @@ -75,13 +74,30 @@ private module CryptographyModel { ) } + /** Gets a reference to a predefined curve class with a specific key size (in bits), as well as the origin of the class. */ + private DataFlow::LocalSourceNode curveClassWithKeySize( + DataFlow::TypeTracker t, int keySize, DataFlow::Node origin + ) { + t.start() and + result = predefinedCurveClass(keySize).getAnImmediateUse() and + origin = result + or + exists(DataFlow::TypeTracker t2 | + result = curveClassWithKeySize(t2, keySize, origin).track(t2, t) + ) + } + + /** Gets a reference to a predefined curve class with a specific key size (in bits), as well as the origin of the class. */ + DataFlow::Node curveClassWithKeySize(int keySize, DataFlow::Node origin) { + curveClassWithKeySize(DataFlow::TypeTracker::end(), keySize, origin).flowsTo(result) + } + /** Gets a reference to a predefined curve class instance with a specific key size (in bits), as well as the origin of the class. */ private DataFlow::LocalSourceNode curveClassInstanceWithKeySize( DataFlow::TypeTracker t, int keySize, DataFlow::Node origin ) { t.start() and - result.(DataFlow::CallCfgNode).getFunction() = curveClassWithKeySize(keySize) and - origin = result + result.(DataFlow::CallCfgNode).getFunction() = curveClassWithKeySize(keySize, origin) or exists(DataFlow::TypeTracker t2 | result = curveClassInstanceWithKeySize(t2, keySize, origin).track(t2, t) @@ -164,6 +180,8 @@ private module CryptographyModel { override int getKeySizeWithOrigin(DataFlow::Node origin) { this.getCurveArg() = Ecc::curveClassInstanceWithKeySize(result, origin) + or + this.getCurveArg() = Ecc::curveClassWithKeySize(result, origin) } // Note: There is not really a key-size argument, since it's always specified by the curve. diff --git a/python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.expected b/python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.expected new file mode 100644 index 00000000000..a94092533f0 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.expected @@ -0,0 +1,5 @@ +| ec_keygen_origin.py:8:1:8:45 | ControlFlowNode for Attribute() | 384 | ec_keygen_origin.py:8:31:8:42 | ControlFlowNode for Attribute | +| ec_keygen_origin.py:9:1:9:43 | ControlFlowNode for Attribute() | 384 | ec_keygen_origin.py:9:31:9:42 | ControlFlowNode for Attribute | +| ec_keygen_origin.py:12:1:12:36 | ControlFlowNode for Attribute() | 384 | ec_keygen_origin.py:11:9:11:20 | ControlFlowNode for Attribute | +| ec_keygen_origin.py:15:1:15:39 | ControlFlowNode for Attribute() | 384 | ec_keygen_origin.py:11:9:11:20 | ControlFlowNode for Attribute | +| ec_keygen_origin.py:20:1:20:32 | ControlFlowNode for Attribute() | 384 | ec_keygen_origin.py:6:58:6:66 | ControlFlowNode for ImportMember | diff --git a/python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.ql b/python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.ql new file mode 100644 index 00000000000..4234177d50d --- /dev/null +++ b/python/ql/test/library-tests/frameworks/cryptography/EcKeygenOrigin.ql @@ -0,0 +1,8 @@ +import semmle.python.dataflow.new.DataFlow +import semmle.python.Concepts + +from Cryptography::PublicKey::KeyGeneration keyGen, int keySize, DataFlow::Node origin +where + keyGen.getLocation().getFile().getShortName() = "ec_keygen_origin.py" and + keySize = keyGen.getKeySizeWithOrigin(origin) +select keyGen, keySize, origin diff --git a/python/ql/test/library-tests/frameworks/cryptography/ec_keygen_origin.py b/python/ql/test/library-tests/frameworks/cryptography/ec_keygen_origin.py new file mode 100644 index 00000000000..c1469adb2ac --- /dev/null +++ b/python/ql/test/library-tests/frameworks/cryptography/ec_keygen_origin.py @@ -0,0 +1,20 @@ +# Since key-size is not specified explicitly as an integer for the predefined +# classes in the `cryptography.hazmat.primitives.asymmetric.ec` module, we need +# special handling of the origin... this test is simply to show off how we handle this. + +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric.ec import SECP384R1 + +ec.generate_private_key(curve=ec.SECP384R1()) # $ PublicKeyGeneration keySize=384 +ec.generate_private_key(curve=ec.SECP384R1) # $ PublicKeyGeneration keySize=384 + +alias = ec.SECP384R1 +ec.generate_private_key(curve=alias) # $ PublicKeyGeneration keySize=384 + +instance = alias() +ec.generate_private_key(curve=instance) # $ PublicKeyGeneration keySize=384 + + +x = SECP384R1 +y = x +ec.generate_private_key(curve=y) # $ PublicKeyGeneration keySize=384 diff --git a/python/ql/test/library-tests/frameworks/cryptography/test_ec.py b/python/ql/test/library-tests/frameworks/cryptography/test_ec.py index 96d60adb2fa..1e1e284dc33 100644 --- a/python/ql/test/library-tests/frameworks/cryptography/test_ec.py +++ b/python/ql/test/library-tests/frameworks/cryptography/test_ec.py @@ -6,7 +6,7 @@ from cryptography.exceptions import InvalidSignature private_key = ec.generate_private_key(curve=ec.SECP384R1()) # $ PublicKeyGeneration keySize=384 -private_key = ec.generate_private_key(curve=ec.SECP384R1) # $ MISSING: PublicKeyGeneration keySize=384 +private_key = ec.generate_private_key(curve=ec.SECP384R1) # $ PublicKeyGeneration keySize=384 public_key = private_key.public_key() HASH_ALGORITHM = hashes.SHA256() From d50f22504e9517ee1ac959ab756ee739476479d9 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 5 May 2021 14:07:15 +0200 Subject: [PATCH 020/272] Python: Fix .expected --- .../test/query-tests/Security/CWE-326/WeakCryptoKey.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-326/WeakCryptoKey.expected b/python/ql/test/query-tests/Security/CWE-326/WeakCryptoKey.expected index 05d759d6f70..dc50ddd7873 100644 --- a/python/ql/test/query-tests/Security/CWE-326/WeakCryptoKey.expected +++ b/python/ql/test/query-tests/Security/CWE-326/WeakCryptoKey.expected @@ -1,8 +1,8 @@ | weak_crypto.py:68:1:68:21 | ControlFlowNode for dsa_gen_key() | Creation of an DSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:16:12:16:15 | ControlFlowNode for IntegerLiteral | 1024 | -| weak_crypto.py:69:1:69:19 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 224 and considered breakable. | weak_crypto.py:22:11:22:24 | ControlFlowNode for Attribute() | 163 | +| weak_crypto.py:69:1:69:19 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 224 and considered breakable. | weak_crypto.py:22:11:22:22 | ControlFlowNode for Attribute | 163 | | weak_crypto.py:70:1:70:28 | ControlFlowNode for rsa_gen_key() | Creation of an RSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:12:12:12:15 | ControlFlowNode for IntegerLiteral | 1024 | | weak_crypto.py:72:1:72:30 | ControlFlowNode for dsa_gen_key() | Creation of an DSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:16:12:16:15 | ControlFlowNode for IntegerLiteral | 1024 | -| weak_crypto.py:73:1:73:25 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 224 and considered breakable. | weak_crypto.py:22:11:22:24 | ControlFlowNode for Attribute() | 163 | +| weak_crypto.py:73:1:73:25 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 224 and considered breakable. | weak_crypto.py:22:11:22:22 | ControlFlowNode for Attribute | 163 | | weak_crypto.py:74:1:74:37 | ControlFlowNode for rsa_gen_key() | Creation of an RSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:12:12:12:15 | ControlFlowNode for IntegerLiteral | 1024 | | weak_crypto.py:76:1:76:22 | ControlFlowNode for Attribute() | Creation of an DSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:16:12:16:15 | ControlFlowNode for IntegerLiteral | 1024 | | weak_crypto.py:77:1:77:22 | ControlFlowNode for Attribute() | Creation of an RSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:12:12:12:15 | ControlFlowNode for IntegerLiteral | 1024 | From b37b15cea40514fcf811621a094ecbec1f922c57 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 7 May 2021 12:33:51 +0200 Subject: [PATCH 021/272] Re-structure imports, add some new comments to tests --- java/ql/src/Security/CWE/CWE-094/JexlInjection.ql | 2 +- java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll | 1 + .../query-tests/security/CWE-094/SandboxedJexl3.java | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql index c97de906aec..c9827d3a123 100644 --- a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql @@ -11,9 +11,9 @@ */ import java -import DataFlow::PathGraph import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.JexlInjection +import DataFlow::PathGraph /** * A taint-tracking configuration for unsafe user input diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 7073c57ff9c..2463777f620 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -80,6 +80,7 @@ private module Frameworks { private import semmle.code.java.security.ResponseSplitting private import semmle.code.java.security.XSS private import semmle.code.java.security.LdapInjection + private import semmle.code.java.security.JexlInjection } private predicate sourceModelCsv(string row) { diff --git a/java/ql/test/query-tests/security/CWE-094/SandboxedJexl3.java b/java/ql/test/query-tests/security/CWE-094/SandboxedJexl3.java index 4c20ac0c901..1950564ecb1 100644 --- a/java/ql/test/query-tests/security/CWE-094/SandboxedJexl3.java +++ b/java/ql/test/query-tests/security/CWE-094/SandboxedJexl3.java @@ -15,17 +15,17 @@ public class SandboxedJexl3 { JexlSandbox sandbox = new JexlSandbox(false); sandbox.white(SandboxedJexl3.class.getCanonicalName()); JexlEngine jexl = new JexlBuilder().sandbox(sandbox).create(); - JexlExpression e = jexl.createExpression(jexlExpr); + JexlExpression e = jexl.createExpression(jexlExpr); // Safe JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // Safe } private static void runJexlExpressionWithUberspectSandbox(String jexlExpr) { JexlUberspect sandbox = new JexlUberspectSandbox(); JexlEngine jexl = new JexlBuilder().uberspect(sandbox).create(); - JexlExpression e = jexl.createExpression(jexlExpr); + JexlExpression e = jexl.createExpression(jexlExpr); // Safe JexlContext jc = new MapContext(); - e.evaluate(jc); + e.evaluate(jc); // Safe } private static JexlBuilder STATIC_JEXL_BUILDER; @@ -39,7 +39,7 @@ public class SandboxedJexl3 { private static void runJexlExpressionViaJxltEngineWithSandbox(String jexlExpr) { JexlEngine jexl = STATIC_JEXL_BUILDER.create(); JxltEngine jxlt = jexl.createJxltEngine(); - jxlt.createExpression(jexlExpr).evaluate(new MapContext()); + jxlt.createExpression(jexlExpr).evaluate(new MapContext()); // Safe } private static class JexlUberspectSandbox implements JexlUberspect { From 2e098f050e07a5647001e98694b83a13470b74e7 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Mon, 10 May 2021 18:33:07 +0200 Subject: [PATCH 022/272] Java: Ignore char array based closeables for CloseReader.ql and CloseWriter.ql --- java/ql/src/Likely Bugs/Resource Leaks/CloseReader.qhelp | 2 +- java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql | 7 ++----- java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.qhelp | 2 +- java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql | 8 ++------ 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.qhelp b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.qhelp index b0ded8e53a1..e5574bfc179 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.qhelp +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.qhelp @@ -14,7 +14,7 @@ but not closed may cause a resource leak.

Ensure that the resource is always closed to avoid a resource leak. Note that, because of exceptions, it is safest to close a resource in a finally block. (However, this is unnecessary for -subclasses of StringReader and ByteArrayInputStream.) +subclasses of CharArrayReader, StringReader and ByteArrayInputStream.)

For Java 7 or later, the recommended way to close resources that implement java.lang.AutoCloseable diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql index 9d62237bd71..5993bd1de2b 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql @@ -17,17 +17,14 @@ import CloseType predicate readerType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | - sup.hasName("Reader") or - sup.hasName("InputStream") or + sup.hasName(["Reader", "InputStream"]) or sup.hasQualifiedName("java.util.zip", "ZipFile") ) } predicate safeReaderType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | - sup.hasName("StringReader") or - sup.hasName("ByteArrayInputStream") or - sup.hasName("StringInputStream") + sup.hasName(["CharArrayReader", "StringReader", "ByteArrayInputStream"]) ) } diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.qhelp b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.qhelp index 0b348a3f9b8..84a50f914f7 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.qhelp +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.qhelp @@ -14,7 +14,7 @@ but not properly closed later may cause a resource leak.

Ensure that the resource is always closed to avoid a resource leak. Note that, because of exceptions, it is safest to close a resource properly in a finally block. (However, this is unnecessary for -subclasses of StringWriter and ByteArrayOutputStream.)

+subclasses of CharArrayWriter, StringWriter and ByteArrayOutputStream.)

For Java 7 or later, the recommended way to close resources that implement java.lang.AutoCloseable is to declare them within a try-with-resources statement, so that they are closed implicitly.

diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql index 113f3bd3267..824951f86f5 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql @@ -16,16 +16,12 @@ import CloseType predicate writerType(RefType t) { - exists(RefType sup | sup = t.getASupertype*() | - sup.hasName("Writer") or - sup.hasName("OutputStream") - ) + exists(RefType sup | sup = t.getASupertype*() | sup.hasName(["Writer", "OutputStream"])) } predicate safeWriterType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | - sup.hasName("StringWriter") or - sup.hasName("ByteArrayOutputStream") + sup.hasName(["CharArrayWriter", "StringWriter", "ByteArrayOutputStream"]) ) } From 8969da7775e88116959fee9ff79c5d3396233d79 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Tue, 11 May 2021 19:21:40 +0200 Subject: [PATCH 023/272] Java: Improve not closing resource query; add tests --- .../Likely Bugs/Resource Leaks/CloseReader.ql | 4 +- .../Likely Bugs/Resource Leaks/CloseWriter.ql | 6 +- .../CloseReader/CloseReader.expected | 6 +- .../CloseReader/CloseReader.java | 89 ++++++++---- .../CloseReader/CloseReader.qlref | 2 +- .../CloseWriter/CloseWriter.expected | 3 + .../CloseWriter/CloseWriter.java | 131 ++++++++++++++++++ .../CloseWriter/CloseWriter.qlref | 1 + 8 files changed, 205 insertions(+), 37 deletions(-) create mode 100644 java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.expected create mode 100644 java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.java create mode 100644 java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.qlref diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql index 5993bd1de2b..73a9c81f343 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql @@ -17,14 +17,14 @@ import CloseType predicate readerType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | - sup.hasName(["Reader", "InputStream"]) or + sup.hasQualifiedName("java.io", ["Reader", "InputStream"]) or sup.hasQualifiedName("java.util.zip", "ZipFile") ) } predicate safeReaderType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | - sup.hasName(["CharArrayReader", "StringReader", "ByteArrayInputStream"]) + sup.hasQualifiedName("java.io", ["CharArrayReader", "StringReader", "ByteArrayInputStream"]) ) } diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql index 824951f86f5..a0714fe3a2f 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql @@ -16,12 +16,14 @@ import CloseType predicate writerType(RefType t) { - exists(RefType sup | sup = t.getASupertype*() | sup.hasName(["Writer", "OutputStream"])) + exists(RefType sup | sup = t.getASupertype*() | + sup.hasQualifiedName("java.io", ["Writer", "OutputStream"]) + ) } predicate safeWriterType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | - sup.hasName(["CharArrayWriter", "StringWriter", "ByteArrayOutputStream"]) + sup.hasQualifiedName("java.io", ["CharArrayWriter", "StringWriter", "ByteArrayOutputStream"]) ) } diff --git a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.expected b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.expected index 12d09e0d65a..e76a4c6d1e4 100644 --- a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.expected +++ b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.expected @@ -1,2 +1,4 @@ -| CloseReader.java:11:42:11:71 | new FileReader(...) | This FileReader is not always closed on method exit. | -| CloseReader.java:44:6:44:40 | new FileInputStream(...) | This FileInputStream is not always closed on method exit. | +| CloseReader.java:18:42:18:71 | new FileReader(...) | This FileReader is not always closed on method exit. | +| CloseReader.java:23:20:23:50 | new FileInputStream(...) | This FileInputStream is not always closed on method exit. | +| CloseReader.java:33:6:33:40 | new FileInputStream(...) | This FileInputStream is not always closed on method exit. | +| CloseReader.java:43:21:43:43 | new ZipFile(...) | This ZipFile is not always closed on method exit. | diff --git a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java index 7d78f8dbfef..b77afc49105 100644 --- a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java +++ b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java @@ -1,41 +1,30 @@ import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.CharArrayReader; +import java.io.Closeable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.zip.ZipFile; class CloseReader { - public static void test1() throws IOException { + void test1() throws IOException { BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt")); System.out.println(br.readLine()); } - public static void test2() throws FileNotFoundException, IOException { - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader("C:\\test.txt")); - System.out.println(br.readLine()); - } - finally { - if(br != null) - br.close(); // 'br' is closed - } + void test2() throws IOException { + InputStream in = new FileInputStream("file.bin"); + in.read(); } - public static void test3() throws IOException { - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader("C:\\test.txt")); - System.out.println(br.readLine()); - } - finally { - cleanup(br); // 'br' is closed within a helper method - } - } - - public static void test4() throws IOException { + void test3() throws IOException { InputStreamReader reader = null; try { // InputStreamReader may throw an exception, in which case the ... @@ -50,7 +39,35 @@ class CloseReader { } } - public static void test5() throws IOException { + void test4() throws IOException { + ZipFile zipFile = new ZipFile("file.zip"); + System.out.println(zipFile.getComment()); + } + + void testCorrect1() throws IOException { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader("C:\\test.txt")); + System.out.println(br.readLine()); + } + finally { + if(br != null) + br.close(); // 'br' is closed + } + } + + void testCorrect2() throws IOException { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader("C:\\test.txt")); + System.out.println(br.readLine()); + } + finally { + cleanup(br); // 'br' is closed within a helper method + } + } + + void testCorrect3() throws IOException { FileInputStream fis = null; InputStreamReader reader = null; try { @@ -66,7 +83,7 @@ class CloseReader { } } - public static void test6() throws IOException { + void testCorrect4() throws IOException { BufferedReader br = null; try { br = new BufferedReader(new FileReader("C:\\test.txt")); @@ -77,15 +94,15 @@ class CloseReader { } } - public static void cleanup(java.io.Closeable... closeables) throws IOException { - for (java.io.Closeable c : closeables) { + void cleanup(Closeable... closeables) throws IOException { + for (Closeable c : closeables) { if (c != null) { c.close(); } } } - public static class LogFile { + static class LogFile { private BufferedReader fileRd; LogFile(String path) { FileReader fr = null; @@ -100,9 +117,21 @@ class CloseReader { private void init(InputStreamReader reader) { fileRd = new BufferedReader(reader); } - public void readStuff() throws java.io.IOException { + public void readStuff() throws IOException { System.out.println(fileRd.readLine()); fileRd.close(); } } + + // Classes which should be ignored + void testIgnore() throws IOException { + Reader r1 = new CharArrayReader(new char[] {'a'}); + r1.read(); + + Reader r2 = new StringReader("a"); + r2.read(); + + InputStream i1 = new ByteArrayInputStream(new byte[] {1}); + i1.read(); + } } diff --git a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.qlref b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.qlref index 3c76645e809..1c808bb9f46 100644 --- a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.qlref +++ b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.qlref @@ -1 +1 @@ -Likely Bugs/Resource Leaks/CloseReader.ql \ No newline at end of file +Likely Bugs/Resource Leaks/CloseReader.ql diff --git a/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.expected b/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.expected new file mode 100644 index 00000000000..efbfe15f2c9 --- /dev/null +++ b/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.expected @@ -0,0 +1,3 @@ +| CloseWriter.java:17:42:17:71 | new FileWriter(...) | This FileWriter is not always closed on method exit. | +| CloseWriter.java:22:22:22:53 | new FileOutputStream(...) | This FileOutputStream is not always closed on method exit. | +| CloseWriter.java:32:6:32:41 | new FileOutputStream(...) | This FileOutputStream is not always closed on method exit. | diff --git a/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.java b/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.java new file mode 100644 index 00000000000..3733237b8de --- /dev/null +++ b/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.java @@ -0,0 +1,131 @@ +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayWriter; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.zip.ZipFile; + +class CloseWriter { + + void test1() throws IOException { + BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\test.txt")); + bw.write("test"); + } + + void test2() throws IOException { + OutputStream out = new FileOutputStream("test.bin"); + out.write(1); + } + + void test3() throws IOException { + OutputStreamWriter writer = null; + try { + // OutputStreamWriter may throw an exception, in which case the ... + writer = new OutputStreamWriter( + // ... FileOutputStream is not closed by the finally block + new FileOutputStream("C:\\test.txt"), "UTF-8"); + writer.write("test"); + } + finally { + if (writer != null) + writer.close(); + } + } + + void testCorrect1() throws IOException { + BufferedWriter bw = null; + try { + bw = new BufferedWriter(new FileWriter("C:\\test.txt")); + bw.write("test"); + } + finally { + if(bw != null) + bw.close(); // 'bw' is closed + } + } + + void testCorrect2() throws IOException { + BufferedWriter bw = null; + try { + bw = new BufferedWriter(new FileWriter("C:\\test.txt")); + bw.write("test"); + } + finally { + cleanup(bw); // 'bw' is closed within a helper method + } + } + + void testCorrect3() throws IOException { + FileOutputStream fos = null; + OutputStreamWriter writer = null; + try { + fos = new FileOutputStream("C:\\test.txt"); + writer = new OutputStreamWriter(fos); + writer.write("test"); + } + finally { + if (fos != null) + fos.close(); // 'fos' is closed + if (writer != null) + writer.close(); // 'writer' is closed + } + } + + void testCorrect4() throws IOException { + BufferedWriter bw = null; + try { + bw = new BufferedWriter(new FileWriter("C:\\test.txt")); + bw.write("test"); + } + finally { + cleanup(null, bw); // 'bw' is closed within a varargs helper method, invoked with multiple args + } + } + + void cleanup(Closeable... closeables) throws IOException { + for (Closeable c : closeables) { + if (c != null) { + c.close(); + } + } + } + + static class LogFile { + private BufferedWriter fileWr; + LogFile(String path) { + FileWriter fw = null; + try { + fw = new FileWriter(path); + } catch (IOException e) { + System.out.println("Error: File not readable: " + path); + System.exit(1); + } + init(fw); + } + private void init(OutputStreamWriter writer) { + fileWr = new BufferedWriter(writer); + } + public void writeStuff() throws IOException { + fileWr.write("test"); + fileWr.close(); + } + } + + // Classes which should be ignored + void testIgnore() throws IOException { + Writer w1 = new CharArrayWriter(); + w1.write("test"); + + Writer w2 = new StringWriter(); + w2.write("test"); + + OutputStream o1 = new ByteArrayOutputStream(); + o1.write(1); + } +} diff --git a/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.qlref b/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.qlref new file mode 100644 index 00000000000..88008367363 --- /dev/null +++ b/java/ql/test/query-tests/CloseResource/CloseWriter/CloseWriter.qlref @@ -0,0 +1 @@ +Likely Bugs/Resource Leaks/CloseWriter.ql From 33641c84f6e83964b59509c44ef3078ee6d4acb3 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 14 May 2021 11:58:27 +0200 Subject: [PATCH 024/272] recognize sanitizing string replace call for regexp-injection --- .../RegExpInjectionCustomizations.qll | 23 +++++++++++++++++ .../Security/CWE-730/RegExpInjection.expected | 24 ++++++++++++++++++ .../Security/CWE-730/RegExpInjection.js | 25 +++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll index df791146b21..af0488a7641 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll @@ -55,4 +55,27 @@ module RegExpInjection { ) } } + + /** + * A global regexp replacement involving the `{`, `[`, or `+` meta-character, viewed as a sanitizer for + * regexp-injection vulnerabilities. + */ + class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall { + MetacharEscapeSanitizer() { + isGlobal() and + ( + RegExp::alwaysMatchesMetaCharacter(getRegExp().getRoot(), ["{", "[", "+"]) + or + // or it's like a wild-card. + RegExp::isWildcardLike(getRegExp().getRoot()) + ) + } + } + + /** + * Meta characters used in the above sanitizer. + */ + private class RegexpMetaChars extends RegExp::MetaCharacter { + RegexpMetaChars() { this = ["{", "[", "+"] } + } } diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 29bad1be0fb..1e0d857fbfb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -44,6 +44,18 @@ nodes | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | +| RegExpInjection.js:60:31:60:56 | input | +| RegExpInjection.js:60:39:60:56 | req.param("input") | +| RegExpInjection.js:60:39:60:56 | req.param("input") | +| RegExpInjection.js:64:14:64:18 | input | +| RegExpInjection.js:64:14:64:18 | input | +| RegExpInjection.js:82:7:82:32 | input | +| RegExpInjection.js:82:15:82:32 | req.param("input") | +| RegExpInjection.js:82:15:82:32 | req.param("input") | +| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | +| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | +| RegExpInjection.js:87:25:87:29 | input | +| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | | tst.js:1:46:1:46 | e | | tst.js:1:46:1:46 | e | | tst.js:2:9:2:21 | data | @@ -99,6 +111,16 @@ edges | RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | +| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | +| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input | +| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | +| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input | +| RegExpInjection.js:82:7:82:32 | input | RegExpInjection.js:87:25:87:29 | input | +| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input | +| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input | +| RegExpInjection.js:87:25:87:29 | input | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | +| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | +| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | | tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | | tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | | tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data | @@ -122,4 +144,6 @@ edges | RegExpInjection.js:47:22:47:26 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:47:22:47:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | | RegExpInjection.js:50:46:50:50 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:50:46:50:50 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value | +| RegExpInjection.js:64:14:64:18 | input | RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:64:14:64:18 | input | This regular expression is constructed from a $@. | RegExpInjection.js:60:39:60:56 | req.param("input") | user-provided value | +| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | This regular expression is constructed from a $@. | RegExpInjection.js:82:15:82:32 | req.param("input") | user-provided value | | tst.js:3:16:3:35 | "^"+ data.name + "$" | tst.js:1:46:1:46 | e | tst.js:3:16:3:35 | "^"+ data.name + "$" | This regular expression is constructed from a $@. | tst.js:1:46:1:46 | e | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js index dc1910b1ae5..e22ec9c6a17 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js @@ -60,4 +60,29 @@ app.get('/findKey', function(req, res) { var key = req.param("key"), input = req.param("input"); Search.search(input); // OK! + + new RegExp(input); // NOT OK + + var sanitized = input.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + new RegExp(sanitized); // OK +}); + +function escape1(pattern) { + return pattern.replace(/[\x00-\x7f]/g, + function(s) { return '\\x' + ('00' + s.charCodeAt().toString(16)).substr(-2); }); +} + +function escape2(str){ + return str.replace(/([\.$?*|{}\(\)\[\]\\\/\+\-^])/g, function(ch){ + return "\\" + ch; +}); +}; + +app.get('/has-sanitizer', function(req, res) { + var input = req.param("input"); + + new RegExp(escape1(input)); // OK + new RegExp(escape2(input)); // OK + + new RegExp("^.*\.(" + input.replace(/,/g, "|") + ")$"); // NOT OK }); From 3766678d60b7b47d5fb9a699155988f6c9ddf0e5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 14 May 2021 13:23:36 +0200 Subject: [PATCH 025/272] move `RegexpMetaChars` into Regexp.qll --- javascript/ql/src/semmle/javascript/Regexp.qll | 14 ++++++++++++-- .../dataflow/RegExpInjectionCustomizations.qll | 7 ------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/Regexp.qll b/javascript/ql/src/semmle/javascript/Regexp.qll index d3b7e9cac7e..c0f01fa130a 100644 --- a/javascript/ql/src/semmle/javascript/Regexp.qll +++ b/javascript/ql/src/semmle/javascript/Regexp.qll @@ -1237,8 +1237,18 @@ module RegExp { } } - private class DefaultMetaCharacter extends MetaCharacter { - DefaultMetaCharacter() { this = ["<", "'", "\""] } + /** + * A meta character used by HTML. + */ + private class HTMLMetaCharacter extends MetaCharacter { + HTMLMetaCharacter() { this = ["<", "'", "\""] } + } + + /** + * A meta character used by regular expressions. + */ + private class RegexpMetaChars extends RegExp::MetaCharacter { + RegexpMetaChars() { this = ["{", "[", "+"] } } /** diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll index af0488a7641..e4555bb5ca8 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll @@ -71,11 +71,4 @@ module RegExpInjection { ) } } - - /** - * Meta characters used in the above sanitizer. - */ - private class RegexpMetaChars extends RegExp::MetaCharacter { - RegexpMetaChars() { this = ["{", "[", "+"] } - } } From 73c7e15580bc9591842dcfc4fa872def88a74ecc Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Fri, 14 May 2021 22:25:00 +0200 Subject: [PATCH 026/272] Java: Add back StringInputStream to CloseReader.ql --- java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql index 73a9c81f343..e93c59b0879 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql @@ -25,6 +25,9 @@ predicate readerType(RefType t) { predicate safeReaderType(RefType t) { exists(RefType sup | sup = t.getASupertype*() | sup.hasQualifiedName("java.io", ["CharArrayReader", "StringReader", "ByteArrayInputStream"]) + or + // Note: It is unclear which specific class this is supposed to match + sup.hasName("StringInputStream") ) } From e205e4bbcee12e121669e661f288d4fc6806e89c Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Fri, 14 May 2021 22:31:14 +0200 Subject: [PATCH 027/272] Java: Add change note for close resource query changes --- .../2021-05-14-close-resource-leaks-improvements.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 java/change-notes/2021-05-14-close-resource-leaks-improvements.md diff --git a/java/change-notes/2021-05-14-close-resource-leaks-improvements.md b/java/change-notes/2021-05-14-close-resource-leaks-improvements.md new file mode 100644 index 00000000000..bae8640d85a --- /dev/null +++ b/java/change-notes/2021-05-14-close-resource-leaks-improvements.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The "Potential input resource leak" (`java/input-resource-leak`) and "Potential output resource leak" (`java/output-resource-leak`) queries have been made more specific to only consider JDK classes and subtypes. Additionally the number of false positives has been reduced. From ef410b998431c1467d10341e9581bf639f6f6b80 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 17 May 2021 19:27:10 +0100 Subject: [PATCH 028/272] Update java/change-notes/2021-05-14-close-resource-leaks-improvements.md --- .../2021-05-14-close-resource-leaks-improvements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/change-notes/2021-05-14-close-resource-leaks-improvements.md b/java/change-notes/2021-05-14-close-resource-leaks-improvements.md index bae8640d85a..08a77840a1f 100644 --- a/java/change-notes/2021-05-14-close-resource-leaks-improvements.md +++ b/java/change-notes/2021-05-14-close-resource-leaks-improvements.md @@ -1,2 +1,2 @@ lgtm,codescanning -* The "Potential input resource leak" (`java/input-resource-leak`) and "Potential output resource leak" (`java/output-resource-leak`) queries have been made more specific to only consider JDK classes and subtypes. Additionally the number of false positives has been reduced. +* The "Potential input resource leak" (`java/input-resource-leak`) and "Potential output resource leak" (`java/output-resource-leak`) queries no longer confuse `java.io` classes such as `Reader` with others that happen to share the same base name. Additionally the number of false positives has been reduced by recognizing `CharArrayReader` and `CharArrayWriter` as types that don't need to be closed. From 904eacf9a21ef22be6cb7dfe3f208d2162648fbd Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 19 May 2021 11:10:06 +0200 Subject: [PATCH 029/272] Python: Use absolute import for PEP249 --- python/ql/src/semmle/python/frameworks/MySQLdb.qll | 2 +- python/ql/src/semmle/python/frameworks/MysqlConnectorPython.qll | 2 +- python/ql/src/semmle/python/frameworks/Psycopg2.qll | 2 +- python/ql/src/semmle/python/frameworks/PyMySQL.qll | 2 +- python/ql/src/semmle/python/frameworks/Stdlib.qll | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/MySQLdb.qll b/python/ql/src/semmle/python/frameworks/MySQLdb.qll index b36bf87c7d9..4f9c799d640 100644 --- a/python/ql/src/semmle/python/frameworks/MySQLdb.qll +++ b/python/ql/src/semmle/python/frameworks/MySQLdb.qll @@ -10,7 +10,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import PEP249 +private import semmle.python.frameworks.PEP249 /** * Provides models for the `MySQLdb` PyPI package. diff --git a/python/ql/src/semmle/python/frameworks/MysqlConnectorPython.qll b/python/ql/src/semmle/python/frameworks/MysqlConnectorPython.qll index 97cd4fd162c..989fb668746 100644 --- a/python/ql/src/semmle/python/frameworks/MysqlConnectorPython.qll +++ b/python/ql/src/semmle/python/frameworks/MysqlConnectorPython.qll @@ -10,7 +10,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import PEP249 +private import semmle.python.frameworks.PEP249 /** * Provides models for the `mysql-connector-python` package. diff --git a/python/ql/src/semmle/python/frameworks/Psycopg2.qll b/python/ql/src/semmle/python/frameworks/Psycopg2.qll index 1cc20026801..d966776b082 100644 --- a/python/ql/src/semmle/python/frameworks/Psycopg2.qll +++ b/python/ql/src/semmle/python/frameworks/Psycopg2.qll @@ -10,7 +10,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import PEP249 +private import semmle.python.frameworks.PEP249 /** * Provides models for the `psycopg2` PyPI package. diff --git a/python/ql/src/semmle/python/frameworks/PyMySQL.qll b/python/ql/src/semmle/python/frameworks/PyMySQL.qll index c078302b73f..452b87ed030 100644 --- a/python/ql/src/semmle/python/frameworks/PyMySQL.qll +++ b/python/ql/src/semmle/python/frameworks/PyMySQL.qll @@ -8,7 +8,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import PEP249 +private import semmle.python.frameworks.PEP249 /** * Provides models for the `PyMySQL` PyPI package. diff --git a/python/ql/src/semmle/python/frameworks/Stdlib.qll b/python/ql/src/semmle/python/frameworks/Stdlib.qll index 07753e9fde5..7acbbcae31b 100644 --- a/python/ql/src/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/src/semmle/python/frameworks/Stdlib.qll @@ -9,7 +9,7 @@ private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import PEP249 +private import semmle.python.frameworks.PEP249 /** Provides models for the Python standard library. */ private module Stdlib { From f66dccafda939f94740e9aaf1a5d44ca625bb647 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 11 May 2021 13:49:56 +0200 Subject: [PATCH 030/272] Python: Rename prettyExp => prettyExpr So we're consistenly using `expr` and not leaving our the `r`. --- .../experimental/dataflow/TestUtil/PrintNode.qll | 12 ++++++------ .../dataflow/tainttracking/TestTaintLib.qll | 2 +- python/ql/test/experimental/meta/InlineTaintTest.qll | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll b/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll index 84f97d3f6ff..46b1bfd9814 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll @@ -1,7 +1,7 @@ import python import semmle.python.dataflow.new.DataFlow -string prettyExp(Expr e) { +string prettyExpr(Expr e) { not e instanceof Num and not e instanceof StrConst and not e instanceof Subscript and @@ -15,17 +15,17 @@ string prettyExp(Expr e) { e.(StrConst).getPrefix() + e.(StrConst).getText() + e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "") or - result = prettyExp(e.(Subscript).getObject()) + "[" + prettyExp(e.(Subscript).getIndex()) + "]" + result = prettyExpr(e.(Subscript).getObject()) + "[" + prettyExpr(e.(Subscript).getIndex()) + "]" or ( if exists(e.(Call).getAnArg()) or exists(e.(Call).getANamedArg()) - then result = prettyExp(e.(Call).getFunc()) + "(..)" - else result = prettyExp(e.(Call).getFunc()) + "()" + then result = prettyExpr(e.(Call).getFunc()) + "(..)" + else result = prettyExpr(e.(Call).getFunc()) + "()" ) or - result = prettyExp(e.(Attribute).getObject()) + "." + e.(Attribute).getName() + result = prettyExpr(e.(Attribute).getObject()) + "." + e.(Attribute).getName() } string prettyNode(DataFlow::Node node) { - if exists(node.asExpr()) then result = prettyExp(node.asExpr()) else result = node.toString() + if exists(node.asExpr()) then result = prettyExpr(node.asExpr()) else result = node.toString() } diff --git a/python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll b/python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll index 32c04f3f3ab..f0e57d66787 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll +++ b/python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll @@ -46,6 +46,6 @@ query predicate test_taint(string arg_location, string test_res, string scope_na arg_location = arg.getLocation().toString() and test_res = test_res and scope_name = call.getScope().getName() and - repr = prettyExp(arg) + repr = prettyExpr(arg) ) } diff --git a/python/ql/test/experimental/meta/InlineTaintTest.qll b/python/ql/test/experimental/meta/InlineTaintTest.qll index dd0865adc4b..da1f084f97d 100644 --- a/python/ql/test/experimental/meta/InlineTaintTest.qll +++ b/python/ql/test/experimental/meta/InlineTaintTest.qll @@ -58,7 +58,7 @@ class InlineTaintTest extends InlineExpectationsTest { exists(DataFlow::Node sink | any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and location = sink.getLocation() and - element = prettyExp(sink.asExpr()) and + element = prettyExpr(sink.asExpr()) and value = "" and tag = "tainted" ) @@ -84,7 +84,7 @@ query predicate untaintedArgumentToEnsureTaintedNotMarkedAsMissing( error = "ERROR, you should add `# $ MISSING: tainted` annotation" and exists(DataFlow::Node sink | sink = shouldBeTainted() and - element = prettyExp(sink.asExpr()) and + element = prettyExpr(sink.asExpr()) and not any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and location = sink.getLocation() and not exists(FalseNegativeExpectation missingResult | From 1af6d97c5118e15811cdf347bf6155a9d5a57a84 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 11 May 2021 14:21:55 +0200 Subject: [PATCH 031/272] Python: Remove straggling f-: annotations --- python/ql/test/library-tests/frameworks/stdlib/Encoding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py index 9a6923ce11f..5ab230ca20f 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py @@ -2,8 +2,8 @@ import pickle import marshal import base64 -pickle.dumps(obj) # $ MISSING: f-:encodeInput=obj f-:encodeOutput=Attribute() f-:encodeFormat=pickle f-:encodeMayExecuteInput -marshal.dumps(obj) # $ MISSING: f-:encodeInput=obj f-:encodeOutput=Attribute() f-:encodeFormat=marshal f-:encodeMayExecuteInput +pickle.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=Attribute() encodeFormat=pickle encodeMayExecuteInput +marshal.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=Attribute() encodeFormat=marshal encodeMayExecuteInput # TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py base64.b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64 From 51a25e45fe55484f39e3ea3d42f0b2d16f045890 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 11 May 2021 14:45:34 +0200 Subject: [PATCH 032/272] Python: Use shared prettyExpr in ConceptsTest.qll This required quite some changes in the expected output. I think it's much more clear what the selected nodes are now :+1: (but it was a bit boring work to fix this up) --- .../test/experimental/meta/ConceptsTest.qll | 32 ++++++------------- .../library-tests/frameworks/dill/Decoding.py | 2 +- .../frameworks/django-v2-v3/response_test.py | 10 +++--- .../django-v2-v3/testproj/settings.py | 2 +- .../frameworks/idna/taint_test.py | 8 ++--- .../frameworks/simplejson/taint_test.py | 14 ++++---- .../frameworks/stdlib-py3/Decoding.py | 6 ++-- .../frameworks/stdlib-py3/Encoding.py | 6 ++-- .../frameworks/stdlib/Decoding.py | 16 +++++----- .../frameworks/stdlib/Encoding.py | 16 +++++----- .../frameworks/ujson/taint_test.py | 20 ++++++------ .../library-tests/frameworks/yaml/Decoding.py | 32 +++++++++---------- 12 files changed, 76 insertions(+), 88 deletions(-) diff --git a/python/ql/test/experimental/meta/ConceptsTest.qll b/python/ql/test/experimental/meta/ConceptsTest.qll index 3800a4cd273..0a75937600f 100644 --- a/python/ql/test/experimental/meta/ConceptsTest.qll +++ b/python/ql/test/experimental/meta/ConceptsTest.qll @@ -2,19 +2,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.Concepts import TestUtilities.InlineExpectationsTest - -string value_from_expr(Expr e) { - // TODO: This one is starting to look like `repr` predicate from TestTaintLib - result = - e.(StrConst).getPrefix() + e.(StrConst).getText() + - e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "") - or - result = e.(Name).getId() - or - not e instanceof StrConst and - not e instanceof Name and - result = e.toString() -} +import experimental.dataflow.TestUtil.PrintNode class SystemCommandExecutionTest extends InlineExpectationsTest { SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" } @@ -27,7 +15,7 @@ class SystemCommandExecutionTest extends InlineExpectationsTest { command = sce.getCommand() and location = command.getLocation() and element = command.toString() and - value = value_from_expr(command.asExpr()) and + value = prettyExpr(command.asExpr()) and tag = "getCommand" ) } @@ -46,7 +34,7 @@ class DecodingTest extends InlineExpectationsTest { exists(DataFlow::Node data | location = data.getLocation() and element = data.toString() and - value = value_from_expr(data.asExpr()) and + value = prettyExpr(data.asExpr()) and ( data = d.getAnInput() and tag = "decodeInput" @@ -84,7 +72,7 @@ class EncodingTest extends InlineExpectationsTest { exists(DataFlow::Node data | location = data.getLocation() and element = data.toString() and - value = value_from_expr(data.asExpr()) and + value = prettyExpr(data.asExpr()) and ( data = e.getAnInput() and tag = "encodeInput" @@ -117,7 +105,7 @@ class CodeExecutionTest extends InlineExpectationsTest { code = ce.getCode() and location = code.getLocation() and element = code.toString() and - value = value_from_expr(code.asExpr()) and + value = prettyExpr(code.asExpr()) and tag = "getCode" ) } @@ -135,7 +123,7 @@ class SqlExecutionTest extends InlineExpectationsTest { sql = e.getSql() and location = e.getLocation() and element = sql.toString() and - value = value_from_expr(sql.asExpr()) and + value = prettyExpr(sql.asExpr()) and tag = "getSql" ) } @@ -218,7 +206,7 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest { exists(HTTP::Server::HttpResponse response | location = response.getLocation() and element = response.toString() and - value = value_from_expr(response.getBody().asExpr()) and + value = prettyExpr(response.getBody().asExpr()) and tag = "responseBody" ) or @@ -257,7 +245,7 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest { exists(HTTP::Server::HttpRedirectResponse redirect | location = redirect.getLocation() and element = redirect.toString() and - value = value_from_expr(redirect.getRedirectLocation().asExpr()) and + value = prettyExpr(redirect.getRedirectLocation().asExpr()) and tag = "redirectLocation" ) ) @@ -275,7 +263,7 @@ class FileSystemAccessTest extends InlineExpectationsTest { path = a.getAPathArgument() and location = a.getLocation() and element = path.toString() and - value = value_from_expr(path.asExpr()) and + value = prettyExpr(path.asExpr()) and tag = "getAPathArgument" ) } @@ -309,7 +297,7 @@ class SafeAccessCheckTest extends InlineExpectationsTest { location = c.getLocation() and ( element = checks.toString() and - value = value_from_expr(checks.asExpr()) and + value = prettyExpr(checks.asExpr()) and tag = "checks" or element = branch.toString() and diff --git a/python/ql/test/library-tests/frameworks/dill/Decoding.py b/python/ql/test/library-tests/frameworks/dill/Decoding.py index a02b013104b..49eb551af04 100644 --- a/python/ql/test/library-tests/frameworks/dill/Decoding.py +++ b/python/ql/test/library-tests/frameworks/dill/Decoding.py @@ -1,3 +1,3 @@ import dill -dill.loads(payload) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=dill decodeMayExecuteInput +dill.loads(payload) # $decodeInput=payload decodeOutput=dill.loads(..) decodeFormat=dill decodeMayExecuteInput diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/response_test.py b/python/ql/test/library-tests/frameworks/django-v2-v3/response_test.py index feeb4d48b88..c7da2f35b6a 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/response_test.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/response_test.py @@ -74,20 +74,20 @@ class CustomRedirectView(RedirectView): # Ensure that simple subclasses are still vuln to XSS def xss__not_found(request): - return HttpResponseNotFound(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=Attribute() + return HttpResponseNotFound(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=request.GET.get(..) # Ensure we still have an XSS sink when manually setting the content_type to HTML def xss__manual_response_type(request): - return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8") # $HttpResponse mimetype=text/html responseBody=Attribute() + return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8") # $HttpResponse mimetype=text/html responseBody=request.GET.get(..) def xss__write(request): response = HttpResponse() # $HttpResponse mimetype=text/html - response.write(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=Attribute() + response.write(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=request.GET.get(..) # This is safe but probably a bug if the argument to `write` is not a result of `json.dumps` or similar. def safe__write_json(request): response = JsonResponse() # $HttpResponse mimetype=application/json - response.write(request.GET.get("name")) # $HttpResponse mimetype=application/json responseBody=Attribute() + response.write(request.GET.get("name")) # $HttpResponse mimetype=application/json responseBody=request.GET.get(..) # Ensure manual subclasses are vulnerable class CustomResponse(HttpResponse): @@ -95,7 +95,7 @@ class CustomResponse(HttpResponse): super().__init__(content, *args, content_type="text/html", **kwargs) def xss__custom_response(request): - return CustomResponse("ACME Responses", request.GET("name")) # $HttpResponse MISSING: mimetype=text/html responseBody=Attribute() SPURIOUS: responseBody="ACME Responses" + return CustomResponse("ACME Responses", request.GET("name")) # $HttpResponse MISSING: mimetype=text/html responseBody=request.GET.get(..) SPURIOUS: responseBody="ACME Responses" class CustomJsonResponse(JsonResponse): def __init__(self, banner, content, *args, **kwargs): diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/testproj/settings.py b/python/ql/test/library-tests/frameworks/django-v2-v3/testproj/settings.py index 1339a14312c..5343182c1c9 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/testproj/settings.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/testproj/settings.py @@ -13,7 +13,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/ from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent #$ getAPathArgument=Path() +BASE_DIR = Path(__file__).resolve().parent.parent #$ getAPathArgument=Path(..) # Quick-start development settings - unsuitable for production diff --git a/python/ql/test/library-tests/frameworks/idna/taint_test.py b/python/ql/test/library-tests/frameworks/idna/taint_test.py index 61b9dad166c..3b20b9e678e 100644 --- a/python/ql/test/library-tests/frameworks/idna/taint_test.py +++ b/python/ql/test/library-tests/frameworks/idna/taint_test.py @@ -5,9 +5,9 @@ def test_idna(): tb = TAINTED_BYTES ensure_tainted( - idna.encode(ts), # $ tainted encodeInput=ts encodeOutput=Attribute() encodeFormat=IDNA - idna.encode(s=ts), # $ tainted encodeInput=ts encodeOutput=Attribute() encodeFormat=IDNA + idna.encode(ts), # $ tainted encodeInput=ts encodeOutput=idna.encode(..) encodeFormat=IDNA + idna.encode(s=ts), # $ tainted encodeInput=ts encodeOutput=idna.encode(..) encodeFormat=IDNA - idna.decode(tb), # $ tainted decodeInput=tb decodeOutput=Attribute() decodeFormat=IDNA - idna.decode(s=tb), # $ tainted decodeInput=tb decodeOutput=Attribute() decodeFormat=IDNA + idna.decode(tb), # $ tainted decodeInput=tb decodeOutput=idna.decode(..) decodeFormat=IDNA + idna.decode(s=tb), # $ tainted decodeInput=tb decodeOutput=idna.decode(..) decodeFormat=IDNA ) diff --git a/python/ql/test/library-tests/frameworks/simplejson/taint_test.py b/python/ql/test/library-tests/frameworks/simplejson/taint_test.py index 6f5d45b0b33..59bec5d6978 100644 --- a/python/ql/test/library-tests/frameworks/simplejson/taint_test.py +++ b/python/ql/test/library-tests/frameworks/simplejson/taint_test.py @@ -5,14 +5,14 @@ def test(): ts = TAINTED_STRING tainted_obj = {"foo": ts} - encoded = simplejson.dumps(tainted_obj) # $ encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj + encoded = simplejson.dumps(tainted_obj) # $ encodeOutput=simplejson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj ensure_tainted( encoded, # $ tainted - simplejson.dumps(tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj - simplejson.dumps(obj=tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj - simplejson.loads(encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded - simplejson.loads(s=encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded + simplejson.dumps(tainted_obj), # $ tainted encodeOutput=simplejson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj + simplejson.dumps(obj=tainted_obj), # $ tainted encodeOutput=simplejson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj + simplejson.loads(encoded), # $ tainted decodeOutput=simplejson.loads(..) decodeFormat=JSON decodeInput=encoded + simplejson.loads(s=encoded), # $ tainted decodeOutput=simplejson.loads(..) decodeFormat=JSON decodeInput=encoded ) # load/dump with file-like @@ -22,7 +22,7 @@ def test(): tainted_filelike.seek(0) ensure_tainted( tainted_filelike, # $ MISSING: tainted - simplejson.load(tainted_filelike), # $ decodeOutput=Attribute() decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted + simplejson.load(tainted_filelike), # $ decodeOutput=simplejson.load(..) decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted ) # load/dump with file-like using keyword-args @@ -32,7 +32,7 @@ def test(): tainted_filelike.seek(0) ensure_tainted( tainted_filelike, # $ MISSING: tainted - simplejson.load(fp=tainted_filelike), # $ decodeOutput=Attribute() decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted + simplejson.load(fp=tainted_filelike), # $ decodeOutput=simplejson.load(..) decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted ) # To make things runable diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py b/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py index 886932495f2..11cca46bdf7 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py @@ -1,6 +1,6 @@ import base64 # TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py -base64.a85decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Ascii85 -base64.b85decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base85 -base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64 +base64.a85decode(payload) # $ decodeInput=payload decodeOutput=base64.a85decode(..) decodeFormat=Ascii85 +base64.b85decode(payload) # $ decodeInput=payload decodeOutput=base64.b85decode(..) decodeFormat=Base85 +base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=base64.decodebytes(..) decodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py index 79fd3a2cd76..7aea6a5e579 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py @@ -1,6 +1,6 @@ import base64 # TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py -base64.a85encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Ascii85 -base64.b85encode(bs)# $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base85 -base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64 +base64.a85encode(bs) # $ encodeInput=bs encodeOutput=base64.a85encode(..) encodeFormat=Ascii85 +base64.b85encode(bs)# $ encodeInput=bs encodeOutput=base64.b85encode(..) encodeFormat=Base85 +base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=base64.encodebytes(..) encodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib/Decoding.py b/python/ql/test/library-tests/frameworks/stdlib/Decoding.py index baf97c90c4d..5d157a61f6e 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Decoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Decoding.py @@ -2,14 +2,14 @@ import pickle import marshal import base64 -pickle.loads(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=pickle decodeMayExecuteInput -marshal.loads(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=marshal decodeMayExecuteInput +pickle.loads(payload) # $ decodeInput=payload decodeOutput=pickle.loads(..) decodeFormat=pickle decodeMayExecuteInput +marshal.loads(payload) # $ decodeInput=payload decodeOutput=marshal.loads(..) decodeFormat=marshal decodeMayExecuteInput # TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py -base64.b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64 -base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64 -base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64 -base64.b32decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base32 -base64.b16decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base16 +base64.b64decode(payload) # $ decodeInput=payload decodeOutput=base64.b64decode(..) decodeFormat=Base64 +base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.standard_b64decode(..) decodeFormat=Base64 +base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.urlsafe_b64decode(..) decodeFormat=Base64 +base64.b32decode(payload) # $ decodeInput=payload decodeOutput=base64.b32decode(..) decodeFormat=Base32 +base64.b16decode(payload) # $ decodeInput=payload decodeOutput=base64.b16decode(..) decodeFormat=Base16 # deprecated since Python 3.1, but still works -base64.decodestring(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64 +base64.decodestring(payload) # $ decodeInput=payload decodeOutput=base64.decodestring(..) decodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py index 5ab230ca20f..2ad51e66fc1 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py @@ -2,14 +2,14 @@ import pickle import marshal import base64 -pickle.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=Attribute() encodeFormat=pickle encodeMayExecuteInput -marshal.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=Attribute() encodeFormat=marshal encodeMayExecuteInput +pickle.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=pickle.dumps(..) encodeFormat=pickle encodeMayExecuteInput +marshal.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=marshal.dumps(..) encodeFormat=marshal encodeMayExecuteInput # TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py -base64.b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64 -base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64 -base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64 -base64.b32encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base32 -base64.b16encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base16 +base64.b64encode(bs) # $ encodeInput=bs encodeOutput=base64.b64encode(..) encodeFormat=Base64 +base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.standard_b64encode(..) encodeFormat=Base64 +base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.urlsafe_b64encode(..) encodeFormat=Base64 +base64.b32encode(bs) # $ encodeInput=bs encodeOutput=base64.b32encode(..) encodeFormat=Base32 +base64.b16encode(bs) # $ encodeInput=bs encodeOutput=base64.b16encode(..) encodeFormat=Base16 # deprecated since Python 3.1, but still works -base64.encodestring(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64 +base64.encodestring(bs) # $ encodeInput=bs encodeOutput=base64.encodestring(..) encodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/ujson/taint_test.py b/python/ql/test/library-tests/frameworks/ujson/taint_test.py index 2c965518393..49423625a58 100644 --- a/python/ql/test/library-tests/frameworks/ujson/taint_test.py +++ b/python/ql/test/library-tests/frameworks/ujson/taint_test.py @@ -5,19 +5,19 @@ def test(): ts = TAINTED_STRING tainted_obj = {"foo": ts} - encoded = ujson.dumps(tainted_obj) # $ encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj + encoded = ujson.dumps(tainted_obj) # $ encodeOutput=ujson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj ensure_tainted( encoded, # $ tainted - ujson.dumps(tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj - ujson.dumps(obj=tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj - ujson.loads(encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded - ujson.loads(obj=encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded + ujson.dumps(tainted_obj), # $ tainted encodeOutput=ujson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj + ujson.dumps(obj=tainted_obj), # $ tainted encodeOutput=ujson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj + ujson.loads(encoded), # $ tainted decodeOutput=ujson.loads(..) decodeFormat=JSON decodeInput=encoded + ujson.loads(obj=encoded), # $ tainted decodeOutput=ujson.loads(..) decodeFormat=JSON decodeInput=encoded - ujson.encode(tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj - ujson.encode(obj=tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj - ujson.decode(encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded - ujson.decode(obj=encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded + ujson.encode(tainted_obj), # $ tainted encodeOutput=ujson.encode(..) encodeFormat=JSON encodeInput=tainted_obj + ujson.encode(obj=tainted_obj), # $ tainted encodeOutput=ujson.encode(..) encodeFormat=JSON encodeInput=tainted_obj + ujson.decode(encoded), # $ tainted decodeOutput=ujson.decode(..) decodeFormat=JSON decodeInput=encoded + ujson.decode(obj=encoded), # $ tainted decodeOutput=ujson.decode(..) decodeFormat=JSON decodeInput=encoded ) # load/dump with file-like @@ -27,7 +27,7 @@ def test(): tainted_filelike.seek(0) ensure_tainted( tainted_filelike, # $ MISSING: tainted - ujson.load(tainted_filelike), # $ decodeOutput=Attribute() decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted + ujson.load(tainted_filelike), # $ decodeOutput=ujson.load(..) decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted ) # load/dump with file-like using keyword-args does not work in `ujson` diff --git a/python/ql/test/library-tests/frameworks/yaml/Decoding.py b/python/ql/test/library-tests/frameworks/yaml/Decoding.py index 987ea76552a..b3cc627883d 100644 --- a/python/ql/test/library-tests/frameworks/yaml/Decoding.py +++ b/python/ql/test/library-tests/frameworks/yaml/Decoding.py @@ -1,37 +1,37 @@ import yaml # Unsafe: -yaml.load(payload) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput -yaml.load(payload, yaml.Loader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput -yaml.unsafe_load(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput -yaml.full_load(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput +yaml.load(payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput +yaml.load(payload, yaml.Loader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput +yaml.unsafe_load(payload) # $ decodeInput=payload decodeOutput=yaml.unsafe_load(..) decodeFormat=YAML decodeMayExecuteInput +yaml.full_load(payload) # $ decodeInput=payload decodeOutput=yaml.full_load(..) decodeFormat=YAML decodeMayExecuteInput # Safe: -yaml.load(payload, yaml.SafeLoader) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML -yaml.load(payload, Loader=yaml.SafeLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML -yaml.load(payload, yaml.BaseLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML -yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML +yaml.load(payload, yaml.SafeLoader) # $ decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML +yaml.load(payload, Loader=yaml.SafeLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML +yaml.load(payload, yaml.BaseLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML +yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=yaml.safe_load(..) decodeFormat=YAML ################################################################################ # load_all variants ################################################################################ # Unsafe: -yaml.load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput -yaml.unsafe_load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput -yaml.full_load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput +yaml.load_all(payload) # $ decodeInput=payload decodeOutput=yaml.load_all(..) decodeFormat=YAML decodeMayExecuteInput +yaml.unsafe_load_all(payload) # $ decodeInput=payload decodeOutput=yaml.unsafe_load_all(..) decodeFormat=YAML decodeMayExecuteInput +yaml.full_load_all(payload) # $ decodeInput=payload decodeOutput=yaml.full_load_all(..) decodeFormat=YAML decodeMayExecuteInput # Safe: -yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML +yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=yaml.safe_load_all(..) decodeFormat=YAML ################################################################################ # C-based loaders with `libyaml` ################################################################################ # Unsafe: -yaml.load(payload, yaml.CLoader) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput -yaml.load(payload, yaml.CFullLoader) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput +yaml.load(payload, yaml.CLoader) # $ decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput +yaml.load(payload, yaml.CFullLoader) # $ decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput # Safe: -yaml.load(payload, yaml.CSafeLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML -yaml.load(payload, yaml.CBaseLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML +yaml.load(payload, yaml.CSafeLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML +yaml.load(payload, yaml.CBaseLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML From 9dbb364ccab04f03d81666f2845cb16921700f28 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 11 May 2021 15:19:06 +0200 Subject: [PATCH 033/272] Python: Move json tests to be part of stdlib This is better, since the modeling is also part of Stdlib.qll --- .../defaultAdditionalTaintStep/test_json.py | 53 ------------------- .../frameworks/stdlib/test_json.py | 40 ++++++++++++++ 2 files changed, 40 insertions(+), 53 deletions(-) delete mode 100644 python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_json.py create mode 100644 python/ql/test/library-tests/frameworks/stdlib/test_json.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_json.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_json.py deleted file mode 100644 index b1b0536b03b..00000000000 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_json.py +++ /dev/null @@ -1,53 +0,0 @@ -# Add taintlib to PATH so it can be imported during runtime without any hassle -import sys; import os; sys.path.append(os.path.dirname(os.path.dirname((__file__)))) -from taintlib import * - -# This has no runtime impact, but allows autocomplete to work -from typing import TYPE_CHECKING -if TYPE_CHECKING: - from ..taintlib import * - - -# Actual tests - -from io import StringIO -import json - -def test(): - print("\n# test") - ts = TAINTED_STRING - - encoded = json.dumps(ts) - - ensure_tainted( - encoded, # $ tainted - json.dumps(ts), # $ tainted - json.dumps(obj=ts), # $ tainted - json.loads(encoded), # $ tainted - json.loads(s=encoded), # $ tainted - ) - - # load/dump with file-like - tainted_filelike = StringIO() - json.dump(ts, tainted_filelike) - - tainted_filelike.seek(0) - ensure_tainted( - tainted_filelike, # $ tainted - json.load(tainted_filelike), # $ tainted - ) - - # load/dump with file-like using keyword-args - tainted_filelike = StringIO() - json.dump(obj=ts, fp=tainted_filelike) - - tainted_filelike.seek(0) - ensure_tainted( - tainted_filelike, # $ tainted - json.load(fp=tainted_filelike), # $ tainted - ) - - -# Make tests runable - -test() diff --git a/python/ql/test/library-tests/frameworks/stdlib/test_json.py b/python/ql/test/library-tests/frameworks/stdlib/test_json.py new file mode 100644 index 00000000000..34f15391f56 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/stdlib/test_json.py @@ -0,0 +1,40 @@ +from io import StringIO +import json + +def test(): + print("\n# test") + ts = TAINTED_STRING + + encoded = json.dumps(ts) # $ encodeOutput=json.dumps(..) encodeFormat=JSON encodeInput=ts + + ensure_tainted( + encoded, # $ tainted + json.dumps(ts), # $ tainted encodeOutput=json.dumps(..) encodeFormat=JSON encodeInput=ts + json.dumps(obj=ts), # $ tainted encodeOutput=json.dumps(..) encodeFormat=JSON encodeInput=ts + json.loads(encoded), # $ tainted decodeOutput=json.loads(..) decodeFormat=JSON decodeInput=encoded + json.loads(s=encoded), # $ tainted decodeOutput=json.loads(..) decodeFormat=JSON decodeInput=encoded + ) + + # load/dump with file-like + tainted_filelike = StringIO() + json.dump(ts, tainted_filelike) # $ encodeFormat=JSON encodeInput=ts + + tainted_filelike.seek(0) + ensure_tainted( + tainted_filelike, # $ tainted + json.load(tainted_filelike), # $ tainted decodeOutput=json.load(..) decodeFormat=JSON decodeInput=tainted_filelike + ) + + # load/dump with file-like using keyword-args + tainted_filelike = StringIO() + json.dump(obj=ts, fp=tainted_filelike) # $ encodeFormat=JSON encodeInput=ts + + tainted_filelike.seek(0) + ensure_tainted( + tainted_filelike, # $ tainted + json.load(fp=tainted_filelike), # $ tainted decodeOutput=json.load(..) decodeFormat=JSON decodeInput=tainted_filelike + ) + + +# Make tests runable +test() From 61ad5d0673915ded9fc65ffbaf5b4ae73de1b74a Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 11 May 2021 14:59:35 +0200 Subject: [PATCH 034/272] Python: Allow printing PostUpdateNode in ConceptsTest.qll See how this works in `test_json.py` --- .../dataflow/TestUtil/PrintNode.qll | 24 +++++++++++++++++++ .../test/experimental/meta/ConceptsTest.qll | 18 +++++++------- .../frameworks/stdlib/test_json.py | 4 ++-- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll b/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll index 46b1bfd9814..6b55beada17 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/PrintNode.qll @@ -26,6 +26,30 @@ string prettyExpr(Expr e) { result = prettyExpr(e.(Attribute).getObject()) + "." + e.(Attribute).getName() } +/** + * Gets pretty-printed version of the DataFlow::Node `node` + */ +bindingset[node] string prettyNode(DataFlow::Node node) { if exists(node.asExpr()) then result = prettyExpr(node.asExpr()) else result = node.toString() } + +/** + * Gets pretty-printed version of the DataFlow::Node `node`, that is suitable for use + * with `TestUtilities.InlineExpectationsTest` (that is, no spaces unless required). + */ +bindingset[node] +string prettyNodeForInlineTest(DataFlow::Node node) { + exists(node.asExpr()) and + result = prettyExpr(node.asExpr()) + or + exists(Expr e | e = node.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() | + // since PostUpdateNode both has space in the `[post ]` annotation, and does + // not pretty print the pre-update node, we do custom handling of this. + result = "[post]" + prettyExpr(e) + ) + or + not exists(node.asExpr()) and + not exists(Expr e | e = node.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) and + result = node.toString() +} diff --git a/python/ql/test/experimental/meta/ConceptsTest.qll b/python/ql/test/experimental/meta/ConceptsTest.qll index 0a75937600f..6c97662feea 100644 --- a/python/ql/test/experimental/meta/ConceptsTest.qll +++ b/python/ql/test/experimental/meta/ConceptsTest.qll @@ -15,7 +15,7 @@ class SystemCommandExecutionTest extends InlineExpectationsTest { command = sce.getCommand() and location = command.getLocation() and element = command.toString() and - value = prettyExpr(command.asExpr()) and + value = prettyNodeForInlineTest(command) and tag = "getCommand" ) } @@ -34,7 +34,7 @@ class DecodingTest extends InlineExpectationsTest { exists(DataFlow::Node data | location = data.getLocation() and element = data.toString() and - value = prettyExpr(data.asExpr()) and + value = prettyNodeForInlineTest(data) and ( data = d.getAnInput() and tag = "decodeInput" @@ -72,7 +72,7 @@ class EncodingTest extends InlineExpectationsTest { exists(DataFlow::Node data | location = data.getLocation() and element = data.toString() and - value = prettyExpr(data.asExpr()) and + value = prettyNodeForInlineTest(data) and ( data = e.getAnInput() and tag = "encodeInput" @@ -105,7 +105,7 @@ class CodeExecutionTest extends InlineExpectationsTest { code = ce.getCode() and location = code.getLocation() and element = code.toString() and - value = prettyExpr(code.asExpr()) and + value = prettyNodeForInlineTest(code) and tag = "getCode" ) } @@ -123,7 +123,7 @@ class SqlExecutionTest extends InlineExpectationsTest { sql = e.getSql() and location = e.getLocation() and element = sql.toString() and - value = prettyExpr(sql.asExpr()) and + value = prettyNodeForInlineTest(sql) and tag = "getSql" ) } @@ -206,7 +206,7 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest { exists(HTTP::Server::HttpResponse response | location = response.getLocation() and element = response.toString() and - value = prettyExpr(response.getBody().asExpr()) and + value = prettyNodeForInlineTest(response.getBody()) and tag = "responseBody" ) or @@ -245,7 +245,7 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest { exists(HTTP::Server::HttpRedirectResponse redirect | location = redirect.getLocation() and element = redirect.toString() and - value = prettyExpr(redirect.getRedirectLocation().asExpr()) and + value = prettyNodeForInlineTest(redirect.getRedirectLocation()) and tag = "redirectLocation" ) ) @@ -263,7 +263,7 @@ class FileSystemAccessTest extends InlineExpectationsTest { path = a.getAPathArgument() and location = a.getLocation() and element = path.toString() and - value = prettyExpr(path.asExpr()) and + value = prettyNodeForInlineTest(path) and tag = "getAPathArgument" ) } @@ -297,7 +297,7 @@ class SafeAccessCheckTest extends InlineExpectationsTest { location = c.getLocation() and ( element = checks.toString() and - value = prettyExpr(checks.asExpr()) and + value = prettyNodeForInlineTest(checks) and tag = "checks" or element = branch.toString() and diff --git a/python/ql/test/library-tests/frameworks/stdlib/test_json.py b/python/ql/test/library-tests/frameworks/stdlib/test_json.py index 34f15391f56..113065c77fd 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/test_json.py +++ b/python/ql/test/library-tests/frameworks/stdlib/test_json.py @@ -17,7 +17,7 @@ def test(): # load/dump with file-like tainted_filelike = StringIO() - json.dump(ts, tainted_filelike) # $ encodeFormat=JSON encodeInput=ts + json.dump(ts, tainted_filelike) # $ encodeOutput=[post]tainted_filelike encodeFormat=JSON encodeInput=ts tainted_filelike.seek(0) ensure_tainted( @@ -27,7 +27,7 @@ def test(): # load/dump with file-like using keyword-args tainted_filelike = StringIO() - json.dump(obj=ts, fp=tainted_filelike) # $ encodeFormat=JSON encodeInput=ts + json.dump(obj=ts, fp=tainted_filelike) # $ encodeOutput=[post]tainted_filelike encodeFormat=JSON encodeInput=ts tainted_filelike.seek(0) ensure_tainted( From 254c769089f9187a0ed6a148b3d6d40980c76e22 Mon Sep 17 00:00:00 2001 From: shati-patel <42641846+shati-patel@users.noreply.github.com> Date: Fri, 21 May 2021 21:41:09 +0100 Subject: [PATCH 035/272] Docs: Describe custom log directory setting in VS Code extension --- .../codeql-for-visual-studio-code/customizing-settings.rst | 4 ++++ .../troubleshooting-codeql-for-visual-studio-code.rst | 2 ++ 2 files changed, 6 insertions(+) diff --git a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst index 8197858d3ab..10c0fb12744 100644 --- a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst +++ b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst @@ -46,6 +46,8 @@ The query history **Format** setting controls how the extension lists queries in To override the default label, you can specify a different format for the query history items. +.. _configuring-settings-for-running-queries: + Configuring settings for running queries ----------------------------------------- @@ -53,6 +55,8 @@ There are a number of settings for **Running Queries**. If your queries run too .. include:: ../reusables/running-queries-debug.rst +To save CodeQL Query Server logs in a custom location, edit the **Running Queries: Custom Log Directory** setting. If you use a custom log directory, the extension doesn't automatically delete the CodeQL Query Server logs. This is useful if you want to investigate these logs to improve the performance of your queries. + Configuring settings for testing queries ----------------------------------------- diff --git a/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst index 80fc5efea0f..3f50d29604b 100644 --- a/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst @@ -38,6 +38,8 @@ You are most likely to need to restart the query server if you make external cha To see the logs from running a particular query, right-click the query in the Query History and select **Show Query Log**. If the log file is too large for the extension to open in the VS Code editor, the file will be displayed in your file explorer so you can open it with an external program. +By default, the extension deletes logs after each workspace session. To override this behavior, you can specify a custom directory for query server logs. For more information, see ":ref:`Customizing settings `." + Exploring problems with running tests ---------------------------------------------- From 8b96ff96013dca8039333bfe83fcc5f978eef91a Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Mon, 12 Apr 2021 21:21:13 +0300 Subject: [PATCH 036/272] First draft of RmiUnsafeDeserialization.ql --- .../CWE/CWE-502/RmiUnsafeDeserialization.ql | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql new file mode 100644 index 00000000000..ddb5cf26f09 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql @@ -0,0 +1,52 @@ +/** + * @name Unsafe deserialization with RMI. + * @description TBD + * @kind problem + * @problem.severity error + * @precision high + * @id java/unsafe-deserialization-rmi + * @tags security + * external/cwe/cwe-502 + */ + +import java +import semmle.code.java.frameworks.Rmi + +private class ObjectInputStream extends RefType { + ObjectInputStream() { hasQualifiedName("java.io", "ObjectInputStream") } +} + +private class BindMethod extends Method { + BindMethod() { + getDeclaringType().hasQualifiedName("java.rmi", "Naming") and + hasName(["bind", "rebind"]) + } +} + +private Method getVulnerableMethod(Type type) { + type.(RefType).getASupertype*() instanceof TypeRemote and + exists(Method m, Type parameterType | + m.getDeclaringType() = type and parameterType = m.getAParamType() + | + not parameterType instanceof PrimitiveType and + not parameterType instanceof TypeString and + not parameterType instanceof ObjectInputStream and + result = m + ) +} + +private class UnsafeRmiBinding extends MethodAccess { + Method vulnerableMethod; + + UnsafeRmiBinding() { + this.getMethod() instanceof BindMethod and + vulnerableMethod = getVulnerableMethod(this.getArgument(1).getType()) + } + + Method getVulnerableMethod() { result = vulnerableMethod } +} + +// TODO: Cover Registry.bind() and rebind() -- test these sinks first + +from UnsafeRmiBinding call +select call, "Unsafe deserialization with RMI in '" + call.getVulnerableMethod() + "' method" From efa4b4f414b73ec078b7740d178576bd2ce690b8 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Thu, 15 Apr 2021 15:37:20 +0300 Subject: [PATCH 037/272] Cover Registry in RmiUnsafeDeserialization.ql --- .../CWE/CWE-502/RmiUnsafeDeserialization.ql | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql index ddb5cf26f09..e90e6704428 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql @@ -1,6 +1,9 @@ /** * @name Unsafe deserialization with RMI. - * @description TBD + * @description Java RMI uses native Java serialization mechanism. + * If a registered remote object has a method that takes a complex object, + * an attacker can take advantage of unsafe Java deserialization mechanism. + * In the worst case, it results in remote code execution. * @kind problem * @problem.severity error * @precision high @@ -16,13 +19,22 @@ private class ObjectInputStream extends RefType { ObjectInputStream() { hasQualifiedName("java.io", "ObjectInputStream") } } +/** + * A method that binds a name to a remote object. + */ private class BindMethod extends Method { BindMethod() { - getDeclaringType().hasQualifiedName("java.rmi", "Naming") and + ( + getDeclaringType().hasQualifiedName("java.rmi", "Naming") or + getDeclaringType().hasQualifiedName("java.rmi.registry", "Registry") + ) and hasName(["bind", "rebind"]) } } +/** + * Looks for a vulnerable method in a `Remote` object. + */ private Method getVulnerableMethod(Type type) { type.(RefType).getASupertype*() instanceof TypeRemote and exists(Method m, Type parameterType | @@ -35,6 +47,9 @@ private Method getVulnerableMethod(Type type) { ) } +/** + * A method call that registers a remote object that has a vulnerable method. + */ private class UnsafeRmiBinding extends MethodAccess { Method vulnerableMethod; @@ -46,7 +61,5 @@ private class UnsafeRmiBinding extends MethodAccess { Method getVulnerableMethod() { result = vulnerableMethod } } -// TODO: Cover Registry.bind() and rebind() -- test these sinks first - from UnsafeRmiBinding call select call, "Unsafe deserialization with RMI in '" + call.getVulnerableMethod() + "' method" From ec6186a1c5d91d8f68c92da45bac985fdd897ec1 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Thu, 15 Apr 2021 16:18:39 +0300 Subject: [PATCH 038/272] Draft of tests for RmiUnsafeDeserialization.ql --- .../CWE-502/RmiUnsafeDeserialization.expected | 0 .../CWE-502/RmiUnsafeDeserialization.java | 24 +++++++++++++++++++ .../CWE-502/RmiUnsafeDeserialization.qlref | 1 + 3 files changed, 25 insertions(+) create mode 100644 java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected create mode 100644 java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java create mode 100644 java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java new file mode 100644 index 00000000000..f3495404e44 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java @@ -0,0 +1,24 @@ +import java.rmi.Naming; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +public class RmiUnsafeDeserialization { + + // BAD (bind a remote object that has a vulnerable method that takes Object) + public static void testRegistryBindWithObjectParameter() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + registry.bind("test", new RemoteObjectWithObject()); + } +} + +interface RemoteObjectWithObjectInterface extends Remote { + + void take(Object obj) throws RemoteException; +} + +class RemoteObjectWithObject implements RemoteObjectWithObjectInterface { + + public void take(Object obj) throws RemoteException {} +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref new file mode 100644 index 00000000000..d750f371002 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql \ No newline at end of file From 3d20330a92144a49b8f564aa8c25a773b38926a1 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Thu, 15 Apr 2021 22:13:19 +0300 Subject: [PATCH 039/272] More tests for RmiUnsafeDeserialization --- .../CWE-502/RmiUnsafeDeserialization.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java index f3495404e44..60c073916b7 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java +++ b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java @@ -1,3 +1,4 @@ +import java.io.ObjectInputStream; import java.rmi.Naming; import java.rmi.Remote; import java.rmi.RemoteException; @@ -10,15 +11,47 @@ public class RmiUnsafeDeserialization { public static void testRegistryBindWithObjectParameter() throws Exception { Registry registry = LocateRegistry.createRegistry(1099); registry.bind("test", new RemoteObjectWithObject()); + registry.rebind("test", new RemoteObjectWithObject()); + } + + // GOOD (bind a remote object that has methods that takes safe parameters) + public static void testRegistryBindWithIntParameter() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + registry.bind("test", new SafeRemoteObject()); + registry.rebind("test", new SafeRemoteObject()); + } + + // BAD (bind a remote object that has a vulnerable method that takes Object) + public static void testNamingBindWithObjectParameter() throws Exception { + Naming.bind("test", new RemoteObjectWithObject()); + Naming.rebind("test", new RemoteObjectWithObject()); + } + + // GOOD (bind a remote object that has methods that takes safe parameters) + public static void testNamingBindWithIntParameter() throws Exception { + Naming.bind("test", new SafeRemoteObject()); + Naming.rebind("test", new SafeRemoteObject()); } } interface RemoteObjectWithObjectInterface extends Remote { - void take(Object obj) throws RemoteException; } class RemoteObjectWithObject implements RemoteObjectWithObjectInterface { - public void take(Object obj) throws RemoteException {} } + +interface SafeRemoteObjectInterface extends Remote { + void take(int n) throws RemoteException; + void take(double n) throws RemoteException; + void take(String s) throws RemoteException; + void take(ObjectInputStream ois) throws RemoteException; +} + +class SafeRemoteObject implements SafeRemoteObjectInterface { + public void take(int n) throws RemoteException {} + public void take(double n) throws RemoteException {} + public void take(String s) throws RemoteException {} + public void take(ObjectInputStream ois) throws RemoteException {} +} \ No newline at end of file From 5ffe04d6a507ac264dbde5c9da4626a33e42d929 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Thu, 15 Apr 2021 22:21:39 +0300 Subject: [PATCH 040/272] Updated expected output for RmiUnsafeDeserialization.java test --- .../security/CWE-502/RmiUnsafeDeserialization.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected index e69de29bb2d..fb91691cc47 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected @@ -0,0 +1,4 @@ +| RmiUnsafeDeserialization.java:13:9:13:59 | bind(...) | Unsafe deserialization with RMI in 'take' method | +| RmiUnsafeDeserialization.java:14:9:14:61 | rebind(...) | Unsafe deserialization with RMI in 'take' method | +| RmiUnsafeDeserialization.java:26:9:26:57 | bind(...) | Unsafe deserialization with RMI in 'take' method | +| RmiUnsafeDeserialization.java:27:9:27:59 | rebind(...) | Unsafe deserialization with RMI in 'take' method | From 0182dfe1c04cd915871655977f4f57b9e2121fdc Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Fri, 16 Apr 2021 16:55:00 +0300 Subject: [PATCH 041/272] Added RmiUnsafeDeserialization.qhelp --- .../CWE/CWE-502/RmiSafeRemoteObject.java | 15 ++++ .../CWE-502/RmiUnsafeDeserialization.qhelp | 68 +++++++++++++++++++ .../CWE/CWE-502/RmiUnsafeDeserialization.ql | 6 +- .../CWE/CWE-502/RmiUnsafeRemoteObject.java | 14 ++++ 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java create mode 100644 java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.qhelp create mode 100644 java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java new file mode 100644 index 00000000000..60a1b49d2fe --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java @@ -0,0 +1,15 @@ +public class Server { + public static void main(String... args) throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + registry.bind("unsafe", new RemoteObjectImpl()); + } +} + +interface RemoteObject extends Remote { + void calculate(int a, double b) throws RemoteException; + void save(String s) throws RemoteException; +} + +class RemoteObjectImpl implements RemoteObject { + // ... +} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.qhelp b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.qhelp new file mode 100644 index 00000000000..1921476ffbd --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.qhelp @@ -0,0 +1,68 @@ + + + + +

+Java RMI uses the default Java serialization mechanism (in other words, ObjectInputStream) +to pass parameters in remote method invocations. This mechanism is known to be unsafe when deserializing +untrusted data. If a registered remote object has a method that accepts a complex object, +an attacker can take advantage of the unsafe deserialization mechanism. +In the worst case, it results in remote code execution. +

+
+ + +

+Use only strings and primitive types in parameters of remote objects. +

+

+Java RMI does not offer API for specifying classes which are only allowed for deserialization. +However, it is possible to set a process-wide deserialization filter that was introduced in JEP 290. +The filter can be set via system or security property jdk.serialFilter. +Make sure that you use the latest Java versions that include JEP 290. +

+

+Consider using other implementations of remote procedure calls. For example, HTTP API with JSON. +Make sure that the underlying deserialization mechanism is properly configured +so that deserialization attacks are not possible. +

+
+ + +

+The following code registers a vulnerable remote object +which has a method that accepts a complex object: +

+ + +

+The next example registers a safe remote object +which has methods that use only primitive types and strings: +

+ + +
+ + +
  • +Oracle: +Remote Method Invocation (RMI). +
  • +
  • +ITNEXT: +Java RMI for pentesters part two — reconnaissance & attack against non-JMX registries. +
  • +
  • +MOGWAI LABS: +Attacking Java RMI services after JEP 290 +
  • +
  • +OWASP: +Deserialization of untrusted data. +
  • +
  • +OpenJDK: +JEP 290: Filter Incoming Serialization Data +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql index e90e6704428..1ece9d14fd9 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql @@ -1,8 +1,8 @@ /** * @name Unsafe deserialization with RMI. - * @description Java RMI uses native Java serialization mechanism. - * If a registered remote object has a method that takes a complex object, - * an attacker can take advantage of unsafe Java deserialization mechanism. + * @description If a registered remote object has a method that accepts a complex object, + * an attacker can take advantage of the unsafe deserialization mechanism + * which is used to pass parameters in RMI. * In the worst case, it results in remote code execution. * @kind problem * @problem.severity error diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java new file mode 100644 index 00000000000..4c04b57cde9 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java @@ -0,0 +1,14 @@ +public class Server { + public static void main(String... args) throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + registry.bind("unsafe", new RemoteObjectImpl()); + } +} + +interface RemoteObject extends Remote { + void action(Object obj) throws RemoteException; +} + +class RemoteObjectImpl implements RemoteObject { + // ... +} \ No newline at end of file From e28f919f3dc88ecf295e01cfa4ac71911735f61e Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Mon, 17 May 2021 13:19:08 +0200 Subject: [PATCH 042/272] Look for remote callable method only in RmiUnsafeDeserialization.ql --- .../Security/CWE/CWE-502/RmiSafeRemoteObject.java | 2 +- .../CWE/CWE-502/RmiUnsafeDeserialization.ql | 13 +++++++------ .../CWE-502/RmiUnsafeDeserialization.expected | 8 ++++---- .../security/CWE-502/RmiUnsafeDeserialization.java | 1 + 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java index 60a1b49d2fe..2f30bc1f3ba 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java @@ -1,7 +1,7 @@ public class Server { public static void main(String... args) throws Exception { Registry registry = LocateRegistry.createRegistry(1099); - registry.bind("unsafe", new RemoteObjectImpl()); + registry.bind("safe", new RemoteObjectImpl()); } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql index 1ece9d14fd9..52c637ebc9f 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql @@ -15,7 +15,7 @@ import java import semmle.code.java.frameworks.Rmi -private class ObjectInputStream extends RefType { +private class ObjectInputStream extends Class { ObjectInputStream() { hasQualifiedName("java.io", "ObjectInputStream") } } @@ -35,9 +35,8 @@ private class BindMethod extends Method { /** * Looks for a vulnerable method in a `Remote` object. */ -private Method getVulnerableMethod(Type type) { - type.(RefType).getASupertype*() instanceof TypeRemote and - exists(Method m, Type parameterType | +private Method getVulnerableMethod(RefType type) { + exists(RemoteCallableMethod m, Type parameterType | m.getDeclaringType() = type and parameterType = m.getAParamType() | not parameterType instanceof PrimitiveType and @@ -61,5 +60,7 @@ private class UnsafeRmiBinding extends MethodAccess { Method getVulnerableMethod() { result = vulnerableMethod } } -from UnsafeRmiBinding call -select call, "Unsafe deserialization with RMI in '" + call.getVulnerableMethod() + "' method" +from UnsafeRmiBinding call, Method vulnerableMethod +where vulnerableMethod = call.getVulnerableMethod() +select call, "Unsafe deserialization with RMI in '$@' method", vulnerableMethod, + vulnerableMethod.getStringSignature() diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected index fb91691cc47..52bcccb15c5 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected @@ -1,4 +1,4 @@ -| RmiUnsafeDeserialization.java:13:9:13:59 | bind(...) | Unsafe deserialization with RMI in 'take' method | -| RmiUnsafeDeserialization.java:14:9:14:61 | rebind(...) | Unsafe deserialization with RMI in 'take' method | -| RmiUnsafeDeserialization.java:26:9:26:57 | bind(...) | Unsafe deserialization with RMI in 'take' method | -| RmiUnsafeDeserialization.java:27:9:27:59 | rebind(...) | Unsafe deserialization with RMI in 'take' method | +| RmiUnsafeDeserialization.java:13:9:13:59 | bind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | +| RmiUnsafeDeserialization.java:14:9:14:61 | rebind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | +| RmiUnsafeDeserialization.java:26:9:26:57 | bind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | +| RmiUnsafeDeserialization.java:27:9:27:59 | rebind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java index 60c073916b7..f8921eda6ce 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java +++ b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java @@ -54,4 +54,5 @@ class SafeRemoteObject implements SafeRemoteObjectInterface { public void take(double n) throws RemoteException {} public void take(String s) throws RemoteException {} public void take(ObjectInputStream ois) throws RemoteException {} + public void safeMethod(Object object) {} // this method is not declared in SafeRemoteObjectInterface } \ No newline at end of file From 2d93eeae33f44c89e2f3d87e21471641f1b5dd58 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Sat, 22 May 2021 20:06:17 +0200 Subject: [PATCH 043/272] Covered deserialization filters in RmiUnsafeDeserialization.ql --- .../CWE/CWE-502/RmiUnsafeDeserialization.ql | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql index 52c637ebc9f..55932027996 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql @@ -1,10 +1,10 @@ /** - * @name Unsafe deserialization with RMI. + * @name Unsafe remote object. * @description If a registered remote object has a method that accepts a complex object, * an attacker can take advantage of the unsafe deserialization mechanism * which is used to pass parameters in RMI. * In the worst case, it results in remote code execution. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id java/unsafe-deserialization-rmi @@ -13,11 +13,9 @@ */ import java +import semmle.code.java.dataflow.TaintTracking import semmle.code.java.frameworks.Rmi - -private class ObjectInputStream extends Class { - ObjectInputStream() { hasQualifiedName("java.io", "ObjectInputStream") } -} +import DataFlow::PathGraph /** * A method that binds a name to a remote object. @@ -33,34 +31,52 @@ private class BindMethod extends Method { } /** - * Looks for a vulnerable method in a `Remote` object. + * Holds if `type` has an unsafe remote method. */ -private Method getVulnerableMethod(RefType type) { +private predicate hasVulnerableMethod(RefType type) { exists(RemoteCallableMethod m, Type parameterType | m.getDeclaringType() = type and parameterType = m.getAParamType() | not parameterType instanceof PrimitiveType and not parameterType instanceof TypeString and - not parameterType instanceof ObjectInputStream and - result = m + not parameterType.(RefType).hasQualifiedName("java.io", "ObjectInputStream") ) } /** - * A method call that registers a remote object that has a vulnerable method. + * A taint-tracking configuration for unsafe remote objects + * that are vulnerable to deserialization attacks. */ -private class UnsafeRmiBinding extends MethodAccess { - Method vulnerableMethod; +private class BindingUnsafeRemoteObjectConfig extends TaintTracking::Configuration { + BindingUnsafeRemoteObjectConfig() { this = "BindingUnsafeRemoteObjectConfig" } - UnsafeRmiBinding() { - this.getMethod() instanceof BindMethod and - vulnerableMethod = getVulnerableMethod(this.getArgument(1).getType()) + override predicate isSource(DataFlow::Node source) { + exists(ConstructorCall cc | cc = source.asExpr() | + hasVulnerableMethod(cc.getConstructedType().getASupertype*()) + ) } - Method getVulnerableMethod() { result = vulnerableMethod } + override predicate isSink(DataFlow::Node sink) { + exists(StaticMethodAccess ma | ma.getArgument(1) = sink.asExpr() | + ma.getMethod() instanceof BindMethod + ) + } + + override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + exists(StaticMethodAccess ma, Method m | m = ma.getMethod() | + m.getDeclaringType().hasQualifiedName("java.rmi.server", "UnicastRemoteObject") and + m.hasName("exportObject") and + not ma.getArgument([2, 4]) + .getType() + .(RefType) + .getASupertype*() + .hasQualifiedName("java.io", "ObjectInputFilter") and + ma.getArgument(0) = fromNode.asExpr() and + ma = toNode.asExpr() + ) + } } -from UnsafeRmiBinding call, Method vulnerableMethod -where vulnerableMethod = call.getVulnerableMethod() -select call, "Unsafe deserialization with RMI in '$@' method", vulnerableMethod, - vulnerableMethod.getStringSignature() +from DataFlow::PathNode source, DataFlow::PathNode sink, BindingUnsafeRemoteObjectConfig conf +where conf.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Binding an unsafe remote object." From d2e29fc72c00c56bdb8002ab92798a67b85b2ef4 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Sun, 23 May 2021 10:18:40 +0200 Subject: [PATCH 044/272] Renamed RmiUnsafeDeserialization.ql -> UnsafeDeserializationRmi.ql --- ...Deserialization.qhelp => UnsafeDeserializationRmi.qhelp} | 0 ...UnsafeDeserialization.ql => UnsafeDeserializationRmi.ql} | 0 .../security/CWE-502/RmiUnsafeDeserialization.qlref | 1 - ...alization.expected => UnsafeDeserializationRmi.expected} | 0 ...feDeserialization.java => UnsafeDeserializationRmi.java} | 6 +++--- .../security/CWE-502/UnsafeDeserializationRmi.qlref | 1 + 6 files changed, 4 insertions(+), 4 deletions(-) rename java/ql/src/experimental/Security/CWE/CWE-502/{RmiUnsafeDeserialization.qhelp => UnsafeDeserializationRmi.qhelp} (100%) rename java/ql/src/experimental/Security/CWE/CWE-502/{RmiUnsafeDeserialization.ql => UnsafeDeserializationRmi.ql} (100%) delete mode 100644 java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref rename java/ql/test/experimental/query-tests/security/CWE-502/{RmiUnsafeDeserialization.expected => UnsafeDeserializationRmi.expected} (100%) rename java/ql/test/experimental/query-tests/security/CWE-502/{RmiUnsafeDeserialization.java => UnsafeDeserializationRmi.java} (98%) create mode 100644 java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.qlref diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.qhelp b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.qhelp rename to java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql rename to java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref b/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref deleted file mode 100644 index d750f371002..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-502/RmiUnsafeDeserialization.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.expected similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.expected rename to java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.expected diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java similarity index 98% rename from java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java rename to java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java index f8921eda6ce..ee0bc3a1989 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/RmiUnsafeDeserialization.java +++ b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java @@ -5,8 +5,8 @@ import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; -public class RmiUnsafeDeserialization { - +public class UnsafeDeserializationRmi { + // BAD (bind a remote object that has a vulnerable method that takes Object) public static void testRegistryBindWithObjectParameter() throws Exception { Registry registry = LocateRegistry.createRegistry(1099); @@ -55,4 +55,4 @@ class SafeRemoteObject implements SafeRemoteObjectInterface { public void take(String s) throws RemoteException {} public void take(ObjectInputStream ois) throws RemoteException {} public void safeMethod(Object object) {} // this method is not declared in SafeRemoteObjectInterface -} \ No newline at end of file +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.qlref b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.qlref new file mode 100644 index 00000000000..fce2e6c6a4a --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql \ No newline at end of file From c837605c856868368deff452eef3b041579b23dc Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Sun, 23 May 2021 13:01:22 +0200 Subject: [PATCH 045/272] Added test cases with sanitizers for UnsafeDeserializationRmi.ql --- .../CWE/CWE-502/UnsafeDeserializationRmi.ql | 10 ++--- .../CWE-502/UnsafeDeserializationRmi.expected | 19 ++++++-- .../CWE-502/UnsafeDeserializationRmi.java | 45 ++++++++++++------- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql index 55932027996..91e38cc373e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql @@ -1,5 +1,5 @@ /** - * @name Unsafe remote object. + * @name Unsafe deserialization in a remotely callable method. * @description If a registered remote object has a method that accepts a complex object, * an attacker can take advantage of the unsafe deserialization mechanism * which is used to pass parameters in RMI. @@ -31,7 +31,7 @@ private class BindMethod extends Method { } /** - * Holds if `type` has an unsafe remote method. + * Holds if `type` has an vulnerable remote method. */ private predicate hasVulnerableMethod(RefType type) { exists(RemoteCallableMethod m, Type parameterType | @@ -57,13 +57,13 @@ private class BindingUnsafeRemoteObjectConfig extends TaintTracking::Configurati } override predicate isSink(DataFlow::Node sink) { - exists(StaticMethodAccess ma | ma.getArgument(1) = sink.asExpr() | + exists(MethodAccess ma | ma.getArgument(1) = sink.asExpr() | ma.getMethod() instanceof BindMethod ) } override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(StaticMethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodAccess ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.rmi.server", "UnicastRemoteObject") and m.hasName("exportObject") and not ma.getArgument([2, 4]) @@ -79,4 +79,4 @@ private class BindingUnsafeRemoteObjectConfig extends TaintTracking::Configurati from DataFlow::PathNode source, DataFlow::PathNode sink, BindingUnsafeRemoteObjectConfig conf where conf.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Binding an unsafe remote object." +select sink.getNode(), source, sink, "Unsafe deserialization in a remote object." diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.expected b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.expected index 52bcccb15c5..188a8649d98 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.expected @@ -1,4 +1,15 @@ -| RmiUnsafeDeserialization.java:13:9:13:59 | bind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | -| RmiUnsafeDeserialization.java:14:9:14:61 | rebind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | -| RmiUnsafeDeserialization.java:26:9:26:57 | bind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | -| RmiUnsafeDeserialization.java:27:9:27:59 | rebind(...) | Unsafe deserialization with RMI in '$@' method | RmiUnsafeDeserialization.java:42:17:42:20 | take | take(Object) | +edges +| UnsafeDeserializationRmi.java:17:68:17:95 | new UnsafeRemoteObjectImpl(...) : UnsafeRemoteObjectImpl | UnsafeDeserializationRmi.java:17:35:17:96 | exportObject(...) | +nodes +| UnsafeDeserializationRmi.java:15:33:15:60 | new UnsafeRemoteObjectImpl(...) | semmle.label | new UnsafeRemoteObjectImpl(...) | +| UnsafeDeserializationRmi.java:16:35:16:62 | new UnsafeRemoteObjectImpl(...) | semmle.label | new UnsafeRemoteObjectImpl(...) | +| UnsafeDeserializationRmi.java:17:35:17:96 | exportObject(...) | semmle.label | exportObject(...) | +| UnsafeDeserializationRmi.java:17:68:17:95 | new UnsafeRemoteObjectImpl(...) : UnsafeRemoteObjectImpl | semmle.label | new UnsafeRemoteObjectImpl(...) : UnsafeRemoteObjectImpl | +| UnsafeDeserializationRmi.java:29:31:29:58 | new UnsafeRemoteObjectImpl(...) | semmle.label | new UnsafeRemoteObjectImpl(...) | +| UnsafeDeserializationRmi.java:30:33:30:60 | new UnsafeRemoteObjectImpl(...) | semmle.label | new UnsafeRemoteObjectImpl(...) | +#select +| UnsafeDeserializationRmi.java:15:33:15:60 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:15:33:15:60 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:15:33:15:60 | new UnsafeRemoteObjectImpl(...) | Unsafe deserialization in a remote object. | +| UnsafeDeserializationRmi.java:16:35:16:62 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:16:35:16:62 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:16:35:16:62 | new UnsafeRemoteObjectImpl(...) | Unsafe deserialization in a remote object. | +| UnsafeDeserializationRmi.java:17:35:17:96 | exportObject(...) | UnsafeDeserializationRmi.java:17:68:17:95 | new UnsafeRemoteObjectImpl(...) : UnsafeRemoteObjectImpl | UnsafeDeserializationRmi.java:17:35:17:96 | exportObject(...) | Unsafe deserialization in a remote object. | +| UnsafeDeserializationRmi.java:29:31:29:58 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:29:31:29:58 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:29:31:29:58 | new UnsafeRemoteObjectImpl(...) | Unsafe deserialization in a remote object. | +| UnsafeDeserializationRmi.java:30:33:30:60 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:30:33:30:60 | new UnsafeRemoteObjectImpl(...) | UnsafeDeserializationRmi.java:30:33:30:60 | new UnsafeRemoteObjectImpl(...) | Unsafe deserialization in a remote object. | diff --git a/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java index ee0bc3a1989..197a1c47843 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java +++ b/java/ql/test/experimental/query-tests/security/CWE-502/UnsafeDeserializationRmi.java @@ -1,58 +1,73 @@ +import java.io.ObjectInputFilter; import java.io.ObjectInputStream; import java.rmi.Naming; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; public class UnsafeDeserializationRmi { - // BAD (bind a remote object that has a vulnerable method that takes Object) + // BAD (bind a remote object that has a vulnerable method) public static void testRegistryBindWithObjectParameter() throws Exception { Registry registry = LocateRegistry.createRegistry(1099); - registry.bind("test", new RemoteObjectWithObject()); - registry.rebind("test", new RemoteObjectWithObject()); + registry.bind("unsafe", new UnsafeRemoteObjectImpl()); + registry.rebind("unsafe", new UnsafeRemoteObjectImpl()); + registry.rebind("unsafe", UnicastRemoteObject.exportObject(new UnsafeRemoteObjectImpl())); } // GOOD (bind a remote object that has methods that takes safe parameters) public static void testRegistryBindWithIntParameter() throws Exception { Registry registry = LocateRegistry.createRegistry(1099); - registry.bind("test", new SafeRemoteObject()); - registry.rebind("test", new SafeRemoteObject()); + registry.bind("safe", new SafeRemoteObjectImpl()); + registry.rebind("safe", new SafeRemoteObjectImpl()); } - // BAD (bind a remote object that has a vulnerable method that takes Object) + // BAD (bind a remote object that has a vulnerable method) public static void testNamingBindWithObjectParameter() throws Exception { - Naming.bind("test", new RemoteObjectWithObject()); - Naming.rebind("test", new RemoteObjectWithObject()); + Naming.bind("unsafe", new UnsafeRemoteObjectImpl()); + Naming.rebind("unsafe", new UnsafeRemoteObjectImpl()); } // GOOD (bind a remote object that has methods that takes safe parameters) public static void testNamingBindWithIntParameter() throws Exception { - Naming.bind("test", new SafeRemoteObject()); - Naming.rebind("test", new SafeRemoteObject()); + Naming.bind("safe", new SafeRemoteObjectImpl()); + Naming.rebind("safe", new SafeRemoteObjectImpl()); + } + + // GOOD (bind a remote object with a deserialization filter) + public static void testRegistryBindWithDeserializationFilter() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + ObjectInputFilter filter = info -> { + if (info.serialClass().getCanonicalName().startsWith("com.safe.package.")) { + return ObjectInputFilter.Status.ALLOWED; + } + return ObjectInputFilter.Status.REJECTED; + }; + registry.rebind("safe", UnicastRemoteObject.exportObject(new UnsafeRemoteObjectImpl(), 12345, filter)); } } -interface RemoteObjectWithObjectInterface extends Remote { +interface UnsafeRemoteObject extends Remote { void take(Object obj) throws RemoteException; } -class RemoteObjectWithObject implements RemoteObjectWithObjectInterface { +class UnsafeRemoteObjectImpl implements UnsafeRemoteObject { public void take(Object obj) throws RemoteException {} } -interface SafeRemoteObjectInterface extends Remote { +interface SafeRemoteObject extends Remote { void take(int n) throws RemoteException; void take(double n) throws RemoteException; void take(String s) throws RemoteException; void take(ObjectInputStream ois) throws RemoteException; } -class SafeRemoteObject implements SafeRemoteObjectInterface { +class SafeRemoteObjectImpl implements SafeRemoteObject { public void take(int n) throws RemoteException {} public void take(double n) throws RemoteException {} public void take(String s) throws RemoteException {} public void take(ObjectInputStream ois) throws RemoteException {} - public void safeMethod(Object object) {} // this method is not declared in SafeRemoteObjectInterface + public void safeMethod(Object object) {} // this method is not declared in SafeRemoteObject } From 1b51dd47ec2717f0da468af752134042cbf9abc3 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Sun, 23 May 2021 13:24:42 +0200 Subject: [PATCH 046/272] Added an example with deserialization filter to UnsafeDeserializationRmi.qhelp --- .../CWE-502/RmiRemoteObjectWithFilter.java | 9 +++++++ .../CWE/CWE-502/RmiSafeRemoteObject.java | 3 +-- .../CWE/CWE-502/RmiUnsafeRemoteObject.java | 3 +-- .../CWE-502/UnsafeDeserializationRmi.qhelp | 26 ++++++++++++++----- 4 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java new file mode 100644 index 00000000000..6d4d2a5357f --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiRemoteObjectWithFilter.java @@ -0,0 +1,9 @@ +public void bindRemoteObject(Registry registry, int port) throws Exception { + ObjectInputFilter filter = info -> { + if (info.serialClass().getCanonicalName().startsWith("com.safe.package.")) { + return ObjectInputFilter.Status.ALLOWED; + } + return ObjectInputFilter.Status.REJECTED; + }; + registry.bind("safer", UnicastRemoteObject.exportObject(new RemoteObjectImpl(), port, filter)); +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java index 2f30bc1f3ba..0c8836522ca 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiSafeRemoteObject.java @@ -1,6 +1,5 @@ public class Server { - public static void main(String... args) throws Exception { - Registry registry = LocateRegistry.createRegistry(1099); + public void bindRemoteObject(Registry registry) throws Exception { registry.bind("safe", new RemoteObjectImpl()); } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java index 4c04b57cde9..96d48e9c9af 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java +++ b/java/ql/src/experimental/Security/CWE/CWE-502/RmiUnsafeRemoteObject.java @@ -1,6 +1,5 @@ public class Server { - public static void main(String... args) throws Exception { - Registry registry = LocateRegistry.createRegistry(1099); + public void bindRemoteObject(Registry registry) throws Exception { registry.bind("unsafe", new RemoteObjectImpl()); } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp index 1921476ffbd..985e3a4c08d 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp @@ -15,14 +15,21 @@ In the worst case, it results in remote code execution.

    Use only strings and primitive types in parameters of remote objects.

    +

    +Set a filter for incoming serialized data by wrapping remote objects using either UnicastRemoteObject.exportObject(Remote, int, ObjectInputFilter) +or UnicastRemoteObject.exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory, ObjectInputFilter) methods. +Those methods accept an ObjectInputFilter that decides which classes are allowed for deserialization. +The filter should allow deserializing only safe classes. +

    -Java RMI does not offer API for specifying classes which are only allowed for deserialization. -However, it is possible to set a process-wide deserialization filter that was introduced in JEP 290. -The filter can be set via system or security property jdk.serialFilter. +It is also possible to set a process-wide deserialization filter. +The filter can be set by with ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter) method, +or by setting system or security property jdk.serialFilter. Make sure that you use the latest Java versions that include JEP 290.

    -Consider using other implementations of remote procedure calls. For example, HTTP API with JSON. +If switching to the latest Java versions is not possible, +consider using other implementations of remote procedure calls. For example, HTTP API with JSON. Make sure that the underlying deserialization mechanism is properly configured so that deserialization attacks are not possible.

    @@ -30,17 +37,22 @@ so that deserialization attacks are not possible.

    -The following code registers a vulnerable remote object -which has a method that accepts a complex object: +The following code registers a remote object +with a vulnerable method that accepts a complex object:

    The next example registers a safe remote object -which has methods that use only primitive types and strings: +whose methods use only primitive types and strings:

    +

    +The next example shows how to set a deserilization filter for a remote object: +

    + +
    From c70651b6feaea545e04107f39dffac31be71a799 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 25 May 2021 11:48:54 +0200 Subject: [PATCH 047/272] always have `arrayLikeElement` as TypeTracking properties --- .../ql/src/semmle/javascript/dataflow/internal/StepSummary.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/StepSummary.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/StepSummary.qll index 2c1362c871d..14a6cdf0d1e 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/StepSummary.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/StepSummary.qll @@ -27,6 +27,8 @@ private module Cached { SharedTypeTrackingStep::loadStoreStep(_, _, this, _) or SharedTypeTrackingStep::loadStoreStep(_, _, _, this) + or + this = DataFlow::PseudoProperties::arrayLikeElement() } } From bfc8845f23daecfaa14f6ac7ba79d7a653577cfd Mon Sep 17 00:00:00 2001 From: shati-patel <42641846+shati-patel@users.noreply.github.com> Date: Tue, 25 May 2021 11:36:18 +0100 Subject: [PATCH 048/272] Update wording --- .../codeql-for-visual-studio-code/customizing-settings.rst | 2 +- docs/codeql/reusables/running-queries-debug.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst index 10c0fb12744..6b1b820b6aa 100644 --- a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst +++ b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst @@ -55,7 +55,7 @@ There are a number of settings for **Running Queries**. If your queries run too .. include:: ../reusables/running-queries-debug.rst -To save CodeQL Query Server logs in a custom location, edit the **Running Queries: Custom Log Directory** setting. If you use a custom log directory, the extension doesn't automatically delete the CodeQL Query Server logs. This is useful if you want to investigate these logs to improve the performance of your queries. +To save query server logs in a custom location, edit the **Running Queries: Custom Log Directory** setting. If you use a custom log directory, the extension saves the logs permanently, instead of deleting them automatically after each workspace session. This is useful if you want to investigate these logs to improve the performance of your queries. Configuring settings for testing queries ----------------------------------------- diff --git a/docs/codeql/reusables/running-queries-debug.rst b/docs/codeql/reusables/running-queries-debug.rst index d7515fc4236..26e7162aa2b 100644 --- a/docs/codeql/reusables/running-queries-debug.rst +++ b/docs/codeql/reusables/running-queries-debug.rst @@ -1 +1 @@ -If you want to examine query performance, enable the **Running Queries: Debug** setting to include timing and tuple counts in the CodeQL Query Server logs shown in the Output view. The tuple count is useful because it indicates the size of the :ref:`predicates ` computed by the query. \ No newline at end of file +If you want to examine query performance, enable the **Running Queries: Debug** setting to include timing and tuple counts. This is shown in the logs in the CodeQL Query Server tab of the Output view. The tuple count is useful because it indicates the size of the :ref:`predicates ` computed by the query. \ No newline at end of file From ee3477c20a41f64c89b3eed6c75f0be9f014818f Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 25 May 2021 14:27:29 +0200 Subject: [PATCH 049/272] Python: Remove dummy clickhouse SQL injection query --- .../CWE-089/ClickHouseSQLInjection.py | 28 --------- .../CWE-089/ClickHouseSQLInjection.qhelp | 59 ------------------- .../CWE-089/ClickHouseSQLInjection.ql | 22 ------- 3 files changed, 109 deletions(-) delete mode 100644 python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.py delete mode 100644 python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.qhelp delete mode 100644 python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.ql diff --git a/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.py b/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.py deleted file mode 100644 index 6668d8eb15f..00000000000 --- a/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.py +++ /dev/null @@ -1,28 +0,0 @@ -from django.conf.urls import url -from clickhouse_driver import Client -from clickhouse_driver import connect -from aioch import Client as aiochClient - -class MyClient(Client): - def dummy(self): - return None - -def show_user(request, username): - - # BAD -- Untrusted user input is directly injected into the sql query using async library 'aioch' - aclient = aiochClient("localhost") - progress = await aclient.execute_with_progress("SELECT * FROM users WHERE username = '%s'" % username) - - # BAD -- Untrusted user input is directly injected into the sql query using native client of library 'clickhouse_driver' - Client('localhost').execute("SELECT * FROM users WHERE username = '%s'" % username) - - # GOOD -- query uses prepared statements - query = "SELECT * FROM users WHERE username = %(username)s" - Client('localhost').execute(query, {"username": username}) - - # BAD -- PEP249 interface - conn = connect('clickhouse://localhost') - cursor = conn.cursor() - cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) - -urlpatterns = [url(r'^users/(?P[^/]+)$', show_user)] diff --git a/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.qhelp b/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.qhelp deleted file mode 100644 index be007545632..00000000000 --- a/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.qhelp +++ /dev/null @@ -1,59 +0,0 @@ - - - - -

    -If a database query (such as a SQL or NoSQL query) is built from -user-provided data without sufficient sanitization, a user -may be able to run malicious database queries. -

    -
    - - -

    -Most database connector libraries offer a way of safely -embedding untrusted data into a query by means of query parameters -or prepared statements. -

    -
    - - -

    -In the following snippet, a user is fetched from a ClickHouse database -using five different queries. In the "BAD" cases the query is built directly from user-controlled data. -In the "GOOD" case the user-controlled data is safely embedded into the query by using query parameters. -

    - -

    -In the first case, the query executed via aioch Client. aioch - is a module -for asynchronous queries to database. -

    - -

    -In the second and third cases, the connection is established via `Client` class. -This class implement different method to execute a query. -

    - -

    -In the forth case, good pattern is presented. Query parameters are send through -second dict-like argument. -

    - -

    -In the fifth case, there is example of PEP249 interface usage. -

    - -

    -In the sixth case, there is custom Class usge which is a subclass of default Client. -

    - - -
    - - -
  • Wikipedia: SQL injection.
  • -
  • OWASP: SQL Injection Prevention Cheat Sheet.
  • -
    -
    diff --git a/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.ql b/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.ql deleted file mode 100644 index f0efb523756..00000000000 --- a/python/ql/src/experimental/Security/CWE-089/ClickHouseSQLInjection.ql +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @id py/yandex/clickhouse-sql-injection - * @name Clickhouse SQL query built from user-controlled sources - * @description Building a SQL query from user-controlled sources is vulnerable to insertion of - * malicious SQL code by the user. - * @kind path-problem - * @problem.severity error - * @precision high - * @tags security - * external/cwe/cwe-089 - * external/owasp/owasp-a1 - */ - -import python -import experimental.semmle.python.frameworks.ClickHouseDriver -import semmle.python.security.dataflow.SqlInjection -import DataFlow::PathGraph - -from SQLInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "This SQL query depends on $@.", source.getNode(), - "a user-provided value" From c9a9535dbcc6b3565032cadb97ead4b883756f36 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 25 May 2021 14:53:09 +0200 Subject: [PATCH 050/272] Python: Use ConceptsTests for ClickHouse SQL libs This did reveal a few places where we do not detect the incoming SQL --- .../frameworks/aioch/ConceptsTest.expected | 0 .../ConceptsTest.ql} | 5 +-- .../semmle/python/frameworks/aioch/options | 1 + .../python/frameworks/aioch/sql_test.py | 30 +++++++++++++ .../ClickHouseDriver.expected | 5 --- .../clickhouse-driver/ClickHouseDriver.py | 32 -------------- .../clickhouse_driver/ConceptsTest.expected | 0 .../clickhouse_driver/ConceptsTest.ql | 3 ++ .../frameworks/clickhouse_driver/sql_test.py | 42 +++++++++++++++++++ .../semmle/python/frameworks/options | 1 + 10 files changed, 78 insertions(+), 41 deletions(-) create mode 100644 python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.expected rename python/ql/test/experimental/semmle/python/frameworks/{clickhouse-driver/ClickHouseDriver.ql => aioch/ConceptsTest.ql} (51%) create mode 100644 python/ql/test/experimental/semmle/python/frameworks/aioch/options create mode 100644 python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py delete mode 100644 python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.expected delete mode 100644 python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.py create mode 100644 python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.expected create mode 100644 python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql create mode 100644 python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py create mode 100644 python/ql/test/experimental/semmle/python/frameworks/options diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.expected b/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.ql b/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql similarity index 51% rename from python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.ql rename to python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql index bedd47c0af6..65b2c78c74a 100644 --- a/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.ql +++ b/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql @@ -1,6 +1,3 @@ import python +import experimental.meta.ConceptsTest import experimental.semmle.python.frameworks.ClickHouseDriver -import semmle.python.Concepts - -from SqlExecution s -select s, s.getSql() diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/options b/python/ql/test/experimental/semmle/python/frameworks/aioch/options new file mode 100644 index 00000000000..cfef58cf2b2 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/frameworks/aioch/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --lang=3 diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py b/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py new file mode 100644 index 00000000000..468791aa3dc --- /dev/null +++ b/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py @@ -0,0 +1,30 @@ +import aioch + + +SQL = "SOME SQL" + + +async def aioch_test(): + client = aioch.Client("localhost") + + await client.execute(SQL) # $ getSql=SQL + await client.execute(query=SQL) # $ MISSING: getSql=SQL + + await client.execute_with_progress(SQL) # $ getSql=SQL + await client.execute_with_progress(query=SQL) # $ MISSING: getSql=SQL + + await client.execute_iter(SQL) # $ getSql=SQL + await client.execute_iter(query=SQL) # $ MISSING: getSql=SQL + + +# Using custom client (this has been seen done for the blocking version in +# `clickhouse_driver` PyPI package) + + +class MyClient(aioch.Client): + pass + + +async def test_custom_client(): + client = MyClient("localhost") + await client.execute(SQL) # $ getSql=SQL diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.expected b/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.expected deleted file mode 100644 index 52aa30cb8c1..00000000000 --- a/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.expected +++ /dev/null @@ -1,5 +0,0 @@ -| ClickHouseDriver.py:15:22:15:106 | ControlFlowNode for Attribute() | ClickHouseDriver.py:15:52:15:105 | ControlFlowNode for BinaryExpr | -| ClickHouseDriver.py:18:5:18:87 | ControlFlowNode for Attribute() | ClickHouseDriver.py:18:33:18:86 | ControlFlowNode for BinaryExpr | -| ClickHouseDriver.py:22:5:22:62 | ControlFlowNode for Attribute() | ClickHouseDriver.py:22:33:22:37 | ControlFlowNode for query | -| ClickHouseDriver.py:27:5:27:74 | ControlFlowNode for Attribute() | ClickHouseDriver.py:27:20:27:73 | ControlFlowNode for BinaryExpr | -| ClickHouseDriver.py:30:5:30:89 | ControlFlowNode for Attribute() | ClickHouseDriver.py:30:35:30:88 | ControlFlowNode for BinaryExpr | diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.py b/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.py deleted file mode 100644 index 7684f3df795..00000000000 --- a/python/ql/test/experimental/semmle/python/frameworks/clickhouse-driver/ClickHouseDriver.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.conf.urls import url -from clickhouse_driver import Client -from clickhouse_driver import connect -from aioch import Client as aiochClient - -# Dummy Client subclass -class MyClient(Client): - def dummy(self): - return None - -def show_user(request, username): - - # BAD -- Untrusted user input is directly injected into the sql query using async library 'aioch' - aclient = aiochClient("localhost") - progress = await aclient.execute_with_progress("SELECT * FROM users WHERE username = '%s'" % username) - - # BAD -- Untrusted user input is directly injected into the sql query using native client of library 'clickhouse_driver' - Client('localhost').execute("SELECT * FROM users WHERE username = '%s'" % username) - - # GOOD -- query uses prepared statements - query = "SELECT * FROM users WHERE username = %(username)s" - Client('localhost').execute(query, {"username": username}) - - # BAD -- Untrusted user input is directly injected into the sql query using PEP249 interface - conn = connect('clickhouse://localhost') - cursor = conn.cursor() - cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) - - # BAD -- Untrusted user input is directly injected into the sql query using MyClient, which is a subclass of Client - MyClient('localhost').execute("SELECT * FROM users WHERE username = '%s'" % username) - -urlpatterns = [url(r'^users/(?P[^/]+)$', show_user)] diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.expected b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql new file mode 100644 index 00000000000..65b2c78c74a --- /dev/null +++ b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql @@ -0,0 +1,3 @@ +import python +import experimental.meta.ConceptsTest +import experimental.semmle.python.frameworks.ClickHouseDriver diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py new file mode 100644 index 00000000000..d1e2491e86e --- /dev/null +++ b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py @@ -0,0 +1,42 @@ +import clickhouse_driver + + +SQL = "SOME SQL" + + +# Normal operation +client = clickhouse_driver.client.Client("localhost") + +client.execute(SQL) # $ MISSING: getSql=SQL +client.execute(query=SQL) # $ MISSING: getSql=SQL + +client.execute_with_progress(SQL) # $ MISSING: getSql=SQL +client.execute_with_progress(query=SQL) # $ MISSING: getSql=SQL + +client.execute_iter(SQL) # $ MISSING: getSql=SQL +client.execute_iter(query=SQL) # $ MISSING: getSql=SQL + + +# commonly used alias +client = clickhouse_driver.Client("localhost") +client.execute(SQL) # $ getSql=SQL + + +# Using PEP249 interface +conn = clickhouse_driver.connect('clickhouse://localhost') +cursor = conn.cursor() +cursor.execute(SQL) # $ getSql=SQL + + +# Using custom client +# +# examples from real world code +# https://github.com/Altinity/clickhouse-mysql-data-reader/blob/3b1b7088751b05e5bbf45890c5949b58208c2343/clickhouse_mysql/dbclient/chclient.py#L10 +# https://github.com/Felixoid/clickhouse-plantuml/blob/d8b2ba7d164a836770ec21f5e4035dfb04c41d9c/clickhouse_plantuml/client.py#L9 + + +class MyClient(clickhouse_driver.Client): + pass + + +MyClient("localhost").execute(SQL) # $ getSql=SQL diff --git a/python/ql/test/experimental/semmle/python/frameworks/options b/python/ql/test/experimental/semmle/python/frameworks/options new file mode 100644 index 00000000000..eb214fc2931 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/frameworks/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 From eb1da152a0d54bff63094056f12ba92a309a9a91 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 25 May 2021 16:13:31 +0200 Subject: [PATCH 051/272] Python: Rewrite ClickHouse SQL lib modeling This did turn into a few changes, that maybe could have been split into separate PRs :shrug: * Rename `ClickHouseDriver` => `ClickhouseDriver`, to better follow import name in `.qll` name * Rewrote modeling to use API graphs * Split modeling of `aioch` into separate `.qll` file, which does re-use the `getExecuteMethodName` predicate. I feel that sharing code between the modeling like this was the best approach, and stuck the `INTERNAL: Do not use.` labels on both modules. * I also added handling of keyword arguments (see change in .py files) --- .../semmle/python/frameworks/Aioch.qll | 52 ++++++++++++ .../python/frameworks/ClickHouseDriver.qll | 85 ------------------- .../python/frameworks/ClickhouseDriver.qll | 65 ++++++++++++++ .../python/frameworks/aioch/ConceptsTest.ql | 2 +- .../python/frameworks/aioch/sql_test.py | 6 +- .../clickhouse_driver/ConceptsTest.ql | 2 +- .../frameworks/clickhouse_driver/sql_test.py | 12 +-- 7 files changed, 128 insertions(+), 96 deletions(-) create mode 100644 python/ql/src/experimental/semmle/python/frameworks/Aioch.qll delete mode 100644 python/ql/src/experimental/semmle/python/frameworks/ClickHouseDriver.qll create mode 100644 python/ql/src/experimental/semmle/python/frameworks/ClickhouseDriver.qll diff --git a/python/ql/src/experimental/semmle/python/frameworks/Aioch.qll b/python/ql/src/experimental/semmle/python/frameworks/Aioch.qll new file mode 100644 index 00000000000..dde97047046 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/frameworks/Aioch.qll @@ -0,0 +1,52 @@ +/** + * Provides classes modeling security-relevant aspects of the `aioch` PyPI package (an + * async-io version of the `clickhouse-driver` PyPI package). + * + * See https://pypi.org/project/aioch/ + */ + +private import python +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.frameworks.PEP249 +private import experimental.semmle.python.frameworks.ClickhouseDriver + +/** + * INTERNAL: Do not use. + * + * Provides models for `aioch` PyPI package (an async-io version of the + * `clickhouse-driver` PyPI package). + * + * See https://pypi.org/project/aioch/ + */ +module Aioch { + /** Provides models for `aioch.Client` class and subclasses. */ + module Client { + /** Gets a reference to the `aioch.Client` class or any subclass. */ + API::Node subclassRef() { + result = API::moduleImport("aioch").getMember("Client").getASubclass*() + } + + /** Gets a reference to an instance of `clickhouse_driver.Client` or any subclass. */ + API::Node instance() { result = subclassRef().getReturn() } + } + + /** + * A call to any of the the execute methods on a `aioch.Client`, which are just async + * versions of the methods in the `clickhouse-driver` PyPI package. + * + * See + * - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute + * - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute_iter + * - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute_with_progress + */ + class ClientExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode { + ClientExecuteCall() { + exists(string methodName | methodName = ClickhouseDriver::getExecuteMethodName() | + this = Client::instance().getMember(methodName).getACall() + ) + } + + override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("query")] } + } +} diff --git a/python/ql/src/experimental/semmle/python/frameworks/ClickHouseDriver.qll b/python/ql/src/experimental/semmle/python/frameworks/ClickHouseDriver.qll deleted file mode 100644 index c456b6bdb89..00000000000 --- a/python/ql/src/experimental/semmle/python/frameworks/ClickHouseDriver.qll +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of `clickhouse-driver` and `aioch` PyPI packages. - * See - * - https://pypi.org/project/clickhouse-driver/ - * - https://pypi.org/project/aioch/ - * - https://clickhouse-driver.readthedocs.io/en/latest/ - */ - -private import python -private import semmle.python.Concepts -private import semmle.python.ApiGraphs -private import semmle.python.frameworks.PEP249 - -/** - * Provides models for `clickhouse-driver` and `aioch` PyPI packages. - * See - * - https://pypi.org/project/clickhouse-driver/ - * - https://pypi.org/project/aioch/ - * - https://clickhouse-driver.readthedocs.io/en/latest/ - */ -module ClickHouseDriver { - /** Gets a reference to the `clickhouse_driver` module. */ - API::Node clickhouse_driver() { result = API::moduleImport("clickhouse_driver") } - - /** Gets a reference to the `aioch` module. This module allows to make async db queries. */ - API::Node aioch() { result = API::moduleImport("aioch") } - - /** - * `clickhouse_driver` implements PEP249, - * providing ways to execute SQL statements against a database. - */ - class ClickHouseDriverPEP249 extends PEP249ModuleApiNode { - ClickHouseDriverPEP249() { this = clickhouse_driver() } - } - - module Client { - /** Gets a reference to a Client call. */ - private DataFlow::Node client_ref() { - result = clickhouse_driver().getMember("Client").getASubclass*().getAUse() - or - result = aioch().getMember("Client").getASubclass*().getAUse() - } - - /** A direct instantiation of `clickhouse_driver.Client`. */ - private class ClientInstantiation extends DataFlow::CallCfgNode { - ClientInstantiation() { this.getFunction() = client_ref() } - } - - /** Gets a reference to an instance of `clickhouse_driver.Client`. */ - private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { - t.start() and - result instanceof ClientInstantiation - or - exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) - } - - /** Gets a reference to an instance of `clickhouse_driver.Client`. */ - DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } - } - - /** clickhouse_driver.Client execute methods */ - private string execute_function() { - result in ["execute_with_progress", "execute", "execute_iter"] - } - - /** Gets a reference to the `clickhouse_driver.Client.execute` method */ - private DataFlow::LocalSourceNode clickhouse_execute(DataFlow::TypeTracker t) { - t.startInAttr(execute_function()) and - result = Client::instance() - or - exists(DataFlow::TypeTracker t2 | result = clickhouse_execute(t2).track(t2, t)) - } - - /** Gets a reference to the `clickhouse_driver.Client.execute` method */ - DataFlow::Node clickhouse_execute() { - clickhouse_execute(DataFlow::TypeTracker::end()).flowsTo(result) - } - - /** A call to the `clickhouse_driver.Client.execute` method */ - private class ExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode { - ExecuteCall() { this.getFunction() = clickhouse_execute() } - - override DataFlow::Node getSql() { result.asCfgNode() = node.getArg(0) } - } -} diff --git a/python/ql/src/experimental/semmle/python/frameworks/ClickhouseDriver.qll b/python/ql/src/experimental/semmle/python/frameworks/ClickhouseDriver.qll new file mode 100644 index 00000000000..8863b1dbe66 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/frameworks/ClickhouseDriver.qll @@ -0,0 +1,65 @@ +/** + * Provides classes modeling security-relevant aspects of the `clickhouse-driver` PyPI package. + * See + * - https://pypi.org/project/clickhouse-driver/ + * - https://clickhouse-driver.readthedocs.io/en/latest/ + */ + +private import python +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.frameworks.PEP249 + +/** + * INTERNAL: Do not use. + * + * Provides models for `clickhouse-driver` PyPI package (imported as `clickhouse_driver`). + * See + * - https://pypi.org/project/clickhouse-driver/ + * - https://clickhouse-driver.readthedocs.io/en/latest/ + */ +module ClickhouseDriver { + /** + * `clickhouse_driver` implements PEP249, + * providing ways to execute SQL statements against a database. + */ + class ClickHouseDriverPEP249 extends PEP249ModuleApiNode { + ClickHouseDriverPEP249() { this = API::moduleImport("clickhouse_driver") } + } + + /** Provides models for `clickhouse_driver.Client` class and subclasses. */ + module Client { + /** Gets a reference to the `clickhouse_driver.Client` class or any subclass. */ + API::Node subclassRef() { + exists(API::Node classRef | + // canonical definition + classRef = API::moduleImport("clickhouse_driver").getMember("client").getMember("Client") + or + // commonly used alias + classRef = API::moduleImport("clickhouse_driver").getMember("Client") + | + result = classRef.getASubclass*() + ) + } + + /** Gets a reference to an instance of `clickhouse_driver.Client` or any subclass. */ + API::Node instance() { result = subclassRef().getReturn() } + } + + /** `clickhouse_driver.Client` execute method names */ + string getExecuteMethodName() { result in ["execute_with_progress", "execute", "execute_iter"] } + + /** + * A call to any of the the execute methods on a `clickhouse_driver.Client` method + * + * See + * - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute + * - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute_iter + * - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute_with_progress + */ + class ClientExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode { + ClientExecuteCall() { this = Client::instance().getMember(getExecuteMethodName()).getACall() } + + override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("query")] } + } +} diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql b/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql index 65b2c78c74a..c0c26131055 100644 --- a/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql +++ b/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql @@ -1,3 +1,3 @@ import python import experimental.meta.ConceptsTest -import experimental.semmle.python.frameworks.ClickHouseDriver +import experimental.semmle.python.frameworks.Aioch diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py b/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py index 468791aa3dc..de6b018b0d4 100644 --- a/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py +++ b/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py @@ -8,13 +8,13 @@ async def aioch_test(): client = aioch.Client("localhost") await client.execute(SQL) # $ getSql=SQL - await client.execute(query=SQL) # $ MISSING: getSql=SQL + await client.execute(query=SQL) # $ getSql=SQL await client.execute_with_progress(SQL) # $ getSql=SQL - await client.execute_with_progress(query=SQL) # $ MISSING: getSql=SQL + await client.execute_with_progress(query=SQL) # $ getSql=SQL await client.execute_iter(SQL) # $ getSql=SQL - await client.execute_iter(query=SQL) # $ MISSING: getSql=SQL + await client.execute_iter(query=SQL) # $ getSql=SQL # Using custom client (this has been seen done for the blocking version in diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql index 65b2c78c74a..86e878cf8c7 100644 --- a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql +++ b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql @@ -1,3 +1,3 @@ import python import experimental.meta.ConceptsTest -import experimental.semmle.python.frameworks.ClickHouseDriver +import experimental.semmle.python.frameworks.ClickhouseDriver diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py index d1e2491e86e..36d4966c186 100644 --- a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py +++ b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py @@ -7,14 +7,14 @@ SQL = "SOME SQL" # Normal operation client = clickhouse_driver.client.Client("localhost") -client.execute(SQL) # $ MISSING: getSql=SQL -client.execute(query=SQL) # $ MISSING: getSql=SQL +client.execute(SQL) # $ getSql=SQL +client.execute(query=SQL) # $ getSql=SQL -client.execute_with_progress(SQL) # $ MISSING: getSql=SQL -client.execute_with_progress(query=SQL) # $ MISSING: getSql=SQL +client.execute_with_progress(SQL) # $ getSql=SQL +client.execute_with_progress(query=SQL) # $ getSql=SQL -client.execute_iter(SQL) # $ MISSING: getSql=SQL -client.execute_iter(query=SQL) # $ MISSING: getSql=SQL +client.execute_iter(SQL) # $ getSql=SQL +client.execute_iter(query=SQL) # $ getSql=SQL # commonly used alias From 1b3f857a2fdeb03e38fe0964c68d984fc23c5feb Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 25 May 2021 16:27:23 +0200 Subject: [PATCH 052/272] Python: Promote ClickHouse SQL models --- docs/codeql/support/reusables/frameworks.rst | 2 ++ python/change-notes/2021-05-25-add-ClickHouse-sql-libs.md | 2 ++ python/ql/src/semmle/python/Frameworks.qll | 2 ++ .../src/{experimental => }/semmle/python/frameworks/Aioch.qll | 2 +- .../semmle/python/frameworks/ClickhouseDriver.qll | 0 .../semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql | 3 --- python/ql/test/experimental/semmle/python/frameworks/options | 1 - .../frameworks/aioch/ConceptsTest.expected | 0 .../python => library-tests}/frameworks/aioch/ConceptsTest.ql | 1 - .../semmle/python => library-tests}/frameworks/aioch/options | 0 .../python => library-tests}/frameworks/aioch/sql_test.py | 0 .../frameworks/clickhouse_driver/ConceptsTest.expected | 0 .../library-tests/frameworks/clickhouse_driver/ConceptsTest.ql | 2 ++ .../frameworks/clickhouse_driver/sql_test.py | 0 14 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 python/change-notes/2021-05-25-add-ClickHouse-sql-libs.md rename python/ql/src/{experimental => }/semmle/python/frameworks/Aioch.qll (96%) rename python/ql/src/{experimental => }/semmle/python/frameworks/ClickhouseDriver.qll (100%) delete mode 100644 python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql delete mode 100644 python/ql/test/experimental/semmle/python/frameworks/options rename python/ql/test/{experimental/semmle/python => library-tests}/frameworks/aioch/ConceptsTest.expected (100%) rename python/ql/test/{experimental/semmle/python => library-tests}/frameworks/aioch/ConceptsTest.ql (50%) rename python/ql/test/{experimental/semmle/python => library-tests}/frameworks/aioch/options (100%) rename python/ql/test/{experimental/semmle/python => library-tests}/frameworks/aioch/sql_test.py (100%) rename python/ql/test/{experimental/semmle/python => library-tests}/frameworks/clickhouse_driver/ConceptsTest.expected (100%) create mode 100644 python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.ql rename python/ql/test/{experimental/semmle/python => library-tests}/frameworks/clickhouse_driver/sql_test.py (100%) diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index be9949aad77..532456d76b4 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -162,6 +162,8 @@ Python built-in support fabric, Utility library invoke, Utility library idna, Utility library + aioch, Database + clickhouse-driver, Database mysql-connector-python, Database MySQLdb, Database psycopg2, Database diff --git a/python/change-notes/2021-05-25-add-ClickHouse-sql-libs.md b/python/change-notes/2021-05-25-add-ClickHouse-sql-libs.md new file mode 100644 index 00000000000..4638180f8c5 --- /dev/null +++ b/python/change-notes/2021-05-25-add-ClickHouse-sql-libs.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added model of SQL execution in `clickhouse-driver` and `aioch` PyPI packages, resulting in additional sinks for the SQL Injection query (`py/sql-injection`). This modeling was originally [submitted as a contribution by @japroc](https://github.com/github/codeql/pull/5889). diff --git a/python/ql/src/semmle/python/Frameworks.qll b/python/ql/src/semmle/python/Frameworks.qll index 3115c3ffac6..96ae176465e 100644 --- a/python/ql/src/semmle/python/Frameworks.qll +++ b/python/ql/src/semmle/python/Frameworks.qll @@ -4,6 +4,8 @@ // If you add modeling of a new framework/library, remember to add it it to the docs in // `docs/codeql/support/reusables/frameworks.rst` +private import semmle.python.frameworks.Aioch +private import semmle.python.frameworks.ClickhouseDriver private import semmle.python.frameworks.Cryptodome private import semmle.python.frameworks.Cryptography private import semmle.python.frameworks.Dill diff --git a/python/ql/src/experimental/semmle/python/frameworks/Aioch.qll b/python/ql/src/semmle/python/frameworks/Aioch.qll similarity index 96% rename from python/ql/src/experimental/semmle/python/frameworks/Aioch.qll rename to python/ql/src/semmle/python/frameworks/Aioch.qll index dde97047046..ede732e35dc 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Aioch.qll +++ b/python/ql/src/semmle/python/frameworks/Aioch.qll @@ -9,7 +9,7 @@ private import python private import semmle.python.Concepts private import semmle.python.ApiGraphs private import semmle.python.frameworks.PEP249 -private import experimental.semmle.python.frameworks.ClickhouseDriver +private import semmle.python.frameworks.ClickhouseDriver /** * INTERNAL: Do not use. diff --git a/python/ql/src/experimental/semmle/python/frameworks/ClickhouseDriver.qll b/python/ql/src/semmle/python/frameworks/ClickhouseDriver.qll similarity index 100% rename from python/ql/src/experimental/semmle/python/frameworks/ClickhouseDriver.qll rename to python/ql/src/semmle/python/frameworks/ClickhouseDriver.qll diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql b/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql deleted file mode 100644 index 86e878cf8c7..00000000000 --- a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.ql +++ /dev/null @@ -1,3 +0,0 @@ -import python -import experimental.meta.ConceptsTest -import experimental.semmle.python.frameworks.ClickhouseDriver diff --git a/python/ql/test/experimental/semmle/python/frameworks/options b/python/ql/test/experimental/semmle/python/frameworks/options deleted file mode 100644 index eb214fc2931..00000000000 --- a/python/ql/test/experimental/semmle/python/frameworks/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=1 diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected similarity index 100% rename from python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.expected rename to python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.ql similarity index 50% rename from python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql rename to python/ql/test/library-tests/frameworks/aioch/ConceptsTest.ql index c0c26131055..b557a0bccb6 100644 --- a/python/ql/test/experimental/semmle/python/frameworks/aioch/ConceptsTest.ql +++ b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.ql @@ -1,3 +1,2 @@ import python import experimental.meta.ConceptsTest -import experimental.semmle.python.frameworks.Aioch diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/options b/python/ql/test/library-tests/frameworks/aioch/options similarity index 100% rename from python/ql/test/experimental/semmle/python/frameworks/aioch/options rename to python/ql/test/library-tests/frameworks/aioch/options diff --git a/python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py b/python/ql/test/library-tests/frameworks/aioch/sql_test.py similarity index 100% rename from python/ql/test/experimental/semmle/python/frameworks/aioch/sql_test.py rename to python/ql/test/library-tests/frameworks/aioch/sql_test.py diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected similarity index 100% rename from python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/ConceptsTest.expected rename to python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected diff --git a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.ql new file mode 100644 index 00000000000..b557a0bccb6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py b/python/ql/test/library-tests/frameworks/clickhouse_driver/sql_test.py similarity index 100% rename from python/ql/test/experimental/semmle/python/frameworks/clickhouse_driver/sql_test.py rename to python/ql/test/library-tests/frameworks/clickhouse_driver/sql_test.py From 706874491bf8bb59e1d4bc8633421dfd63e67150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Fri, 21 May 2021 13:44:03 +0200 Subject: [PATCH 053/272] Remove XSS sink for Java --- java/ql/src/semmle/code/java/security/XSS.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/src/semmle/code/java/security/XSS.qll b/java/ql/src/semmle/code/java/security/XSS.qll index 486e8053953..14f10cad9c8 100644 --- a/java/ql/src/semmle/code/java/security/XSS.qll +++ b/java/ql/src/semmle/code/java/security/XSS.qll @@ -34,7 +34,6 @@ private class DefaultXssSinkModel extends SinkModelCsv { override predicate row(string row) { row = [ - "javax.servlet.http;HttpServletResponse;false;sendError;(int,String);;Argument[1];xss", "android.webkit;WebView;false;loadData;;;Argument[0];xss", "android.webkit;WebView;false;loadUrl;;;Argument[0];xss", "android.webkit;WebView;false;loadDataWithBaseURL;;;Argument[1];xss" From 735e4e4b7bcf0e55811652e7fd02639c51eb312b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Fri, 28 May 2021 13:44:16 +0200 Subject: [PATCH 054/272] update failing tests --- .../query-tests/security/CWE-079/semmle/tests/XSS.expected | 4 ---- .../test/query-tests/security/CWE-079/semmle/tests/XSS.java | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected index ed67a987e84..c800f627c64 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected @@ -1,19 +1,15 @@ edges | XSS.java:23:21:23:48 | getParameter(...) : String | XSS.java:23:5:23:70 | ... + ... | -| XSS.java:27:21:27:48 | getParameter(...) : String | XSS.java:27:5:27:70 | ... + ... | | XSS.java:38:67:38:87 | getPathInfo(...) : String | XSS.java:38:30:38:87 | ... + ... | | XSS.java:41:36:41:56 | getPathInfo(...) : String | XSS.java:41:36:41:67 | getBytes(...) | nodes | XSS.java:23:5:23:70 | ... + ... | semmle.label | ... + ... | | XSS.java:23:21:23:48 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| XSS.java:27:5:27:70 | ... + ... | semmle.label | ... + ... | -| XSS.java:27:21:27:48 | getParameter(...) : String | semmle.label | getParameter(...) : String | | XSS.java:38:30:38:87 | ... + ... | semmle.label | ... + ... | | XSS.java:38:67:38:87 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | | XSS.java:41:36:41:56 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | | XSS.java:41:36:41:67 | getBytes(...) | semmle.label | getBytes(...) | #select | XSS.java:23:5:23:70 | ... + ... | XSS.java:23:21:23:48 | getParameter(...) : String | XSS.java:23:5:23:70 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:23:21:23:48 | getParameter(...) | user-provided value | -| XSS.java:27:5:27:70 | ... + ... | XSS.java:27:21:27:48 | getParameter(...) : String | XSS.java:27:5:27:70 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:27:21:27:48 | getParameter(...) | user-provided value | | XSS.java:38:30:38:87 | ... + ... | XSS.java:38:67:38:87 | getPathInfo(...) : String | XSS.java:38:30:38:87 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:38:67:38:87 | getPathInfo(...) | user-provided value | | XSS.java:41:36:41:67 | getBytes(...) | XSS.java:41:36:41:56 | getPathInfo(...) : String | XSS.java:41:36:41:67 | getBytes(...) | Cross-site scripting vulnerability due to $@. | XSS.java:41:36:41:56 | getPathInfo(...) | user-provided value | diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java index 54e60a13086..3ebaac47819 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java @@ -22,7 +22,7 @@ public class XSS extends HttpServlet { response.getWriter().print( "The page \"" + request.getParameter("page") + "\" was not found."); - // BAD: a request parameter is written directly to an error response page + // GOOD: servlet API encodes the error message HTML for the HTML context response.sendError(HttpServletResponse.SC_NOT_FOUND, "The page \"" + request.getParameter("page") + "\" was not found."); @@ -30,7 +30,7 @@ public class XSS extends HttpServlet { response.sendError(HttpServletResponse.SC_NOT_FOUND, "The page \"" + encodeForHtml(request.getParameter("page")) + "\" was not found."); - // FALSE NEGATIVE: passed through function that is not a secure check + // GOOD: servlet API encodes the error message HTML for the HTML context response.sendError(HttpServletResponse.SC_NOT_FOUND, "The page \"" + capitalizeName(request.getParameter("page")) + "\" was not found."); From db2f05ac248566ed9612bd615879e97a3381f424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Fri, 28 May 2021 13:48:48 +0200 Subject: [PATCH 055/272] Updated Java change notes --- java/change-notes/2021-05-28-remove-senderror-xss-sink.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 java/change-notes/2021-05-28-remove-senderror-xss-sink.md diff --git a/java/change-notes/2021-05-28-remove-senderror-xss-sink.md b/java/change-notes/2021-05-28-remove-senderror-xss-sink.md new file mode 100644 index 00000000000..7b4959f7056 --- /dev/null +++ b/java/change-notes/2021-05-28-remove-senderror-xss-sink.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The query "Cross-site scripting" (`java/xss`) has been improved to report fewer false positives by removing the `javax.servlet.http.HttpServletResponse.sendError` sink since the Servlet API implementations already encode the error message for the HTML context. From 5a894ac7f78c4617d242d719581452df7bc2148b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Fri, 28 May 2021 14:07:12 +0200 Subject: [PATCH 056/272] update java library coverage documentation --- java/documentation/library-coverage/flow-model-coverage.csv | 2 +- java/documentation/library-coverage/flow-model-coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/flow-model-coverage.csv b/java/documentation/library-coverage/flow-model-coverage.csv index cf97071ad92..73f06306193 100644 --- a/java/documentation/library-coverage/flow-model-coverage.csv +++ b/java/documentation/library-coverage/flow-model-coverage.csv @@ -15,7 +15,7 @@ java.nio,10,,2,,10,,,,,,,,,2, java.util,,,13,,,,,,,,,,,13, javax.naming.directory,1,,,,,,1,,,,,,,, javax.net.ssl,2,,,,,,,,2,,,,,, -javax.servlet,4,21,2,,,3,,,,,,1,21,2, +javax.servlet,3,21,2,,,3,,,,,,,21,2, javax.validation,1,1,,1,,,,,,,,,1,, javax.ws.rs.core,1,,,,,1,,,,,,,,, javax.xml.transform.sax,,,4,,,,,,,,,,,4, diff --git a/java/documentation/library-coverage/flow-model-coverage.rst b/java/documentation/library-coverage/flow-model-coverage.rst index 8bb20a9b6c3..bad79a93c06 100644 --- a/java/documentation/library-coverage/flow-model-coverage.rst +++ b/java/documentation/library-coverage/flow-model-coverage.rst @@ -12,8 +12,8 @@ Java framework & library support `Apache Commons IO `_,``org.apache.commons.io``,,22,,,,,,,, Google,``com.google.common.*``,,97,6,,6,,,,, Java Standard Library,``java.*``,3,41,15,13,,,,,,2 - Java extensions,``javax.*``,22,8,12,,,1,,1,1, + Java extensions,``javax.*``,22,8,11,,,,,1,1, `Spring `_,``org.springframework.*``,29,,14,,,,,14,, Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.dom4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,5,37,,,,,17,, - Totals,,84,821,91,13,6,7,,33,1,2 + Totals,,84,821,90,13,6,6,,33,1,2 From f60df3b26a315d665df05edf7bdb99cfa59341be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Fri, 28 May 2021 13:52:31 +0200 Subject: [PATCH 057/272] Update java/change-notes/2021-05-28-remove-senderror-xss-sink.md Co-authored-by: Chris Smowton --- java/change-notes/2021-05-28-remove-senderror-xss-sink.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/change-notes/2021-05-28-remove-senderror-xss-sink.md b/java/change-notes/2021-05-28-remove-senderror-xss-sink.md index 7b4959f7056..5dd245bcb52 100644 --- a/java/change-notes/2021-05-28-remove-senderror-xss-sink.md +++ b/java/change-notes/2021-05-28-remove-senderror-xss-sink.md @@ -1,2 +1,2 @@ lgtm,codescanning -* The query "Cross-site scripting" (`java/xss`) has been improved to report fewer false positives by removing the `javax.servlet.http.HttpServletResponse.sendError` sink since the Servlet API implementations already encode the error message for the HTML context. +* The query "Cross-site scripting" (`java/xss`) has been improved to report fewer false positives by removing the `javax.servlet.http.HttpServletResponse.sendError` sink since Servlet API implementations generally already escape the error message, preventing script injection. From 62c6bee5f89cf3a2edf9a82bfaf675c78f9b772f Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Sat, 29 May 2021 09:21:20 +0200 Subject: [PATCH 058/272] Simplified UnsafeDeserializationRmi.ql --- .../Security/CWE/CWE-502/UnsafeDeserializationRmi.ql | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql index 91e38cc373e..f870d6f423e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.ql @@ -66,11 +66,7 @@ private class BindingUnsafeRemoteObjectConfig extends TaintTracking::Configurati exists(MethodAccess ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.rmi.server", "UnicastRemoteObject") and m.hasName("exportObject") and - not ma.getArgument([2, 4]) - .getType() - .(RefType) - .getASupertype*() - .hasQualifiedName("java.io", "ObjectInputFilter") and + not m.getParameterType([2, 4]).(RefType).hasQualifiedName("java.io", "ObjectInputFilter") and ma.getArgument(0) = fromNode.asExpr() and ma = toNode.asExpr() ) From b28d6391666f53767b85209138759fbf5922e7f5 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Sat, 29 May 2021 09:32:08 +0200 Subject: [PATCH 059/272] Fixed errors in UnsafeDeserializationRmi.qhelp --- .../Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp index 985e3a4c08d..ea06f315cc4 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp @@ -15,7 +15,7 @@ In the worst case, it results in remote code execution.

    Use only strings and primitive types in parameters of remote objects.

    -

    +

    Set a filter for incoming serialized data by wrapping remote objects using either UnicastRemoteObject.exportObject(Remote, int, ObjectInputFilter) or UnicastRemoteObject.exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory, ObjectInputFilter) methods. Those methods accept an ObjectInputFilter that decides which classes are allowed for deserialization. @@ -26,6 +26,7 @@ It is also possible to set a process-wide deserialization filter. The filter can be set by with ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter) method, or by setting system or security property jdk.serialFilter. Make sure that you use the latest Java versions that include JEP 290. +Please note that the query is not sensitive to this mitigation.

    If switching to the latest Java versions is not possible, @@ -62,11 +63,11 @@ Oracle:

  • ITNEXT: -Java RMI for pentesters part two — reconnaissance & attack against non-JMX registries. +Java RMI for pentesters part two - reconnaissance & attack against non-JMX registries.
  • MOGWAI LABS: -Attacking Java RMI services after JEP 290 +Attacking Java RMI services after JEP 290
  • OWASP: From 41d034d5a0fda510d4a5461dc3558e3136ca8edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Sun, 30 May 2021 00:22:40 +0200 Subject: [PATCH 060/272] Attempt to use information-leak sink category --- .../CWE/CWE-209/StackTraceExposure.ql | 14 +++++++---- .../code/java/dataflow/ExternalFlow.qll | 1 + .../code/java/security/InformationLeak.qll | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 java/ql/src/semmle/code/java/security/InformationLeak.qll diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index 3426d9f6f62..b82edc2efc6 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -16,6 +16,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.XSS +import semmle.code.java.security.InformationLeak /** * One of the `printStackTrace()` overloads on `Throwable`. @@ -83,14 +84,17 @@ predicate stackTraceExpr(Expr exception, MethodAccess stackTraceString) { ) } -class StackTraceStringToXssSinkFlowConfig extends TaintTracking::Configuration { - StackTraceStringToXssSinkFlowConfig() { - this = "StackTraceExposure::StackTraceStringToXssSinkFlowConfig" +class StackTraceStringToHTTPResponseSinkFlowConfig extends TaintTracking::Configuration { + StackTraceStringToHTTPResponseSinkFlowConfig() { + this = "StackTraceExposure::StackTraceStringToHTTPResponseSinkFlowConfig" } override predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) } - override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } + override predicate isSink(DataFlow::Node sink) { + sink instanceof XssSink or + sink instanceof InformationLeakSink + } } /** @@ -106,7 +110,7 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) { * A stringified stack trace flows to an external sink. */ predicate stringifiedStackFlowsExternally(XssSink externalExpr, Expr stackTrace) { - exists(MethodAccess stackTraceString, StackTraceStringToXssSinkFlowConfig conf | + exists(MethodAccess stackTraceString, StackTraceStringToHTTPResponseSinkFlowConfig conf | stackTraceExpr(stackTrace, stackTraceString) and conf.hasFlow(DataFlow::exprNode(stackTraceString), externalExpr) ) diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 33a146d07fe..92dfb5a733c 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -79,6 +79,7 @@ private module Frameworks { private import semmle.code.java.frameworks.guava.Guava private import semmle.code.java.frameworks.jackson.JacksonSerializability private import semmle.code.java.security.ResponseSplitting + private import semmle.code.java.security.InformationLeak private import semmle.code.java.security.XSS private import semmle.code.java.security.LdapInjection private import semmle.code.java.security.XPath diff --git a/java/ql/src/semmle/code/java/security/InformationLeak.qll b/java/ql/src/semmle/code/java/security/InformationLeak.qll new file mode 100644 index 00000000000..4cb12c3d3d9 --- /dev/null +++ b/java/ql/src/semmle/code/java/security/InformationLeak.qll @@ -0,0 +1,23 @@ +/** Provides classes to reason about System Information Leak vulnerabilities. */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.ExternalFlow + +/** CSV sink models representing methods not susceptible to XSS but outputing to an HTTP response body. */ +private class DefaultInformationLeakSinkModel extends SinkModelCsv { + override predicate row(string row) { + row = + [ + "javax.servlet.http;HttpServletResponse;false;sendError;(int,String);;Argument[1];information-leak" + ] + } +} + +/** A sink that represent a method that outputs data to an HTTP response. */ +abstract class InformationLeakSink extends DataFlow::Node { } + +/** A default sink representing methods outputing data to an HTTP response. */ +private class DefaultInformationLeakSink extends InformationLeakSink { + DefaultInformationLeakSink() { sinkNode(this, "information-leak") } +} From 35d7fda5e2fb4325933ea39b728498f0bea8049f Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 31 May 2021 13:08:09 +0200 Subject: [PATCH 061/272] update typescript to 4.3 in the extractor --- javascript/extractor/lib/typescript/package.json | 2 +- javascript/extractor/lib/typescript/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index cb3119c7ab2..953f69edb1e 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "4.2.2" + "typescript": "^4.3.2" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index 84f20b2c51c..7488658d581 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -6,7 +6,7 @@ version "12.7.11" resolved node-12.7.11.tgz#be879b52031cfb5d295b047f5462d8ef1a716446 -typescript@4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.2.tgz#1450f020618f872db0ea17317d16d8da8ddb8c4c" - integrity sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ== +typescript@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" + integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== From 2cc2d116bc80d6c1b4ceda7fe67311a0170ddbd4 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 31 May 2021 13:08:24 +0200 Subject: [PATCH 062/272] bump extractor version --- javascript/extractor/src/com/semmle/js/extractor/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index 7c5a8a25984..5d417940d75 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -43,7 +43,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2021-03-19"; + public static final String EXTRACTOR_VERSION = "2021-05-31"; public static final Pattern NEWLINE = Pattern.compile("\n"); From e6b1c61e816c5e6afc47eb1438f2222d75e9b2c7 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 31 May 2021 13:08:43 +0200 Subject: [PATCH 063/272] add tests for TypeScript 4.3 --- .../TypeScript/IndexTypes/test.expected | 2 + .../TypeScript/IndexTypes/test.ql | 3 + .../TypeScript/IndexTypes/tsconfig.json | 1 + .../TypeScript/IndexTypes/tst.ts | 8 ++ .../TypeScript/Types/tests.expected | 87 +++++++++++++++++++ .../library-tests/TypeScript/Types/tst.ts | 63 +++++++++++++- 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 javascript/ql/test/library-tests/TypeScript/IndexTypes/test.expected create mode 100644 javascript/ql/test/library-tests/TypeScript/IndexTypes/test.ql create mode 100644 javascript/ql/test/library-tests/TypeScript/IndexTypes/tsconfig.json create mode 100644 javascript/ql/test/library-tests/TypeScript/IndexTypes/tst.ts diff --git a/javascript/ql/test/library-tests/TypeScript/IndexTypes/test.expected b/javascript/ql/test/library-tests/TypeScript/IndexTypes/test.expected new file mode 100644 index 00000000000..4779b178e4f --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/IndexTypes/test.expected @@ -0,0 +1,2 @@ +| Foo | boolean | +| typeof Foo in global scope | string | diff --git a/javascript/ql/test/library-tests/TypeScript/IndexTypes/test.ql b/javascript/ql/test/library-tests/TypeScript/IndexTypes/test.ql new file mode 100644 index 00000000000..ff6a2a4836f --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/IndexTypes/test.ql @@ -0,0 +1,3 @@ +import javascript + +query Type stringIndexType(Type t) { result = t.getStringIndexType() } diff --git a/javascript/ql/test/library-tests/TypeScript/IndexTypes/tsconfig.json b/javascript/ql/test/library-tests/TypeScript/IndexTypes/tsconfig.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/IndexTypes/tsconfig.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeScript/IndexTypes/tst.ts b/javascript/ql/test/library-tests/TypeScript/IndexTypes/tst.ts new file mode 100644 index 00000000000..9035ff2b2ac --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/IndexTypes/tst.ts @@ -0,0 +1,8 @@ + // static index signature + class Foo { + static hello = "world"; + static [n: string]: string; + [n: string]: boolean; + } + Foo["whatever"] = "foo"; + new Foo()["something"] = true; \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected index 7c8159a9b10..187c0c7e6ce 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected @@ -127,6 +127,54 @@ getExprType | tst.ts:69:24:69:45 | {yetAno ... : true} | MyUnion2 | | tst.ts:69:25:69:38 | yetAnotherType | true | | tst.ts:69:41:69:44 | true | true | +| tst.ts:71:8:71:11 | TS43 | typeof TS43 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:74:5:74:22 | get size(): number | number | +| tst.ts:74:9:74:12 | size | number | +| tst.ts:75:5:75:47 | set siz ... olean); | number | +| tst.ts:75:9:75:12 | size | number | +| tst.ts:75:14:75:18 | value | string \| number \| boolean | +| tst.ts:78:16:78:20 | Thing | Thing | +| tst.ts:79:13:79:13 | 0 | 0 | +| tst.ts:81:5:83:5 | get siz ... ;\\n } | number | +| tst.ts:81:9:81:12 | size | number | +| tst.ts:82:14:82:23 | this.#size | number | +| tst.ts:85:5:87:5 | set siz ... ;\\n } | number | +| tst.ts:85:9:85:12 | size | number | +| tst.ts:85:14:85:18 | value | string \| number \| boolean | +| tst.ts:86:7:86:16 | this.#size | number | +| tst.ts:86:7:86:32 | this.#s ... (value) | number | +| tst.ts:86:20:86:25 | Number | NumberConstructor | +| tst.ts:86:20:86:32 | Number(value) | number | +| tst.ts:86:27:86:31 | value | string \| number \| boolean | +| tst.ts:91:9:91:13 | Super | Super | +| tst.ts:92:5:92:10 | random | () => number | +| tst.ts:92:5:94:5 | random( ... ;\\n } | () => number | +| tst.ts:93:14:93:14 | 4 | 4 | +| tst.ts:97:9:97:11 | Sub | Sub | +| tst.ts:97:21:97:25 | Super | Super | +| tst.ts:98:5:100:5 | overrid ... ;\\n } | () => number | +| tst.ts:98:14:98:19 | random | () => number | +| tst.ts:99:14:99:25 | super.random | () => number | +| tst.ts:99:14:99:27 | super.random() | number | +| tst.ts:99:14:99:32 | super.random() * 10 | number | +| tst.ts:99:20:99:25 | random | () => number | +| tst.ts:99:31:99:32 | 10 | 10 | +| tst.ts:104:16:104:16 | s | string | +| tst.ts:106:13:106:18 | hello | any | +| tst.ts:106:21:106:21 | s | string | +| tst.ts:110:15:110:16 | s2 | "1-2-3" | +| tst.ts:112:3:112:9 | s1 = s2 | "1-2-3" | +| tst.ts:112:8:112:9 | s2 | "1-2-3" | +| tst.ts:116:9:116:11 | Foo | Foo | +| tst.ts:117:5:119:5 | #someMe ... ;\\n } | () => number | +| tst.ts:118:14:118:15 | 42 | 42 | +| tst.ts:121:5:123:5 | get #so ... ;\\n } | number | +| tst.ts:122:14:122:16 | 100 | 100 | +| tst.ts:125:5:125:16 | publicMethod | () => number | +| tst.ts:125:5:128:5 | publicM ... ;\\n } | () => number | +| tst.ts:126:7:126:22 | this.#someMethod | () => number | +| tst.ts:126:7:126:24 | this.#someMethod() | number | +| tst.ts:127:14:127:28 | this.#someValue | number | | type_alias.ts:3:5:3:5 | b | boolean | | type_alias.ts:7:5:7:5 | c | ValueOrArray | | type_alias.ts:14:9:14:32 | [proper ... ]: Json | any | @@ -180,6 +228,11 @@ getTypeDefinitionType | tst.ts:58:1:60:1 | interfa ... mber;\\n} | HasArea | | tst.ts:65:1:65:54 | type My ... true}; | MyUnion | | tst.ts:68:1:68:49 | type My ... true}; | MyUnion2 | +| tst.ts:73:3:76:3 | interfa ... n);\\n } | ThingI | +| tst.ts:78:10:88:3 | class T ... }\\n } | Thing | +| tst.ts:91:3:95:3 | class S ... }\\n } | Super | +| tst.ts:97:3:101:3 | class S ... }\\n } | Sub | +| tst.ts:116:3:129:3 | class F ... }\\n } | Foo | | type_alias.ts:1:1:1:17 | type B = boolean; | boolean | | type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray | | type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json | @@ -288,6 +341,34 @@ getTypeExprType | tst.ts:68:27:68:48 | {yetAno ... : true} | { yetAnotherType: true; } | | tst.ts:68:44:68:47 | true | true | | tst.ts:69:13:69:20 | MyUnion2 | MyUnion2 | +| tst.ts:73:13:73:18 | ThingI | ThingI | +| tst.ts:74:17:74:22 | number | number | +| tst.ts:75:21:75:26 | number | number | +| tst.ts:75:21:75:45 | number ... boolean | string \| number \| boolean | +| tst.ts:75:30:75:35 | string | string | +| tst.ts:75:39:75:45 | boolean | boolean | +| tst.ts:78:33:78:38 | ThingI | ThingI | +| tst.ts:81:17:81:22 | number | number | +| tst.ts:85:21:85:26 | string | string | +| tst.ts:85:21:85:45 | string ... boolean | string \| number \| boolean | +| tst.ts:85:30:85:35 | number | number | +| tst.ts:85:39:85:45 | boolean | boolean | +| tst.ts:92:15:92:20 | number | number | +| tst.ts:98:24:98:29 | number | number | +| tst.ts:104:19:104:24 | string | string | +| tst.ts:104:29:104:34 | hello | any | +| tst.ts:104:37:104:42 | string | string | +| tst.ts:109:22:109:27 | number | number | +| tst.ts:109:29:109:29 | - | any | +| tst.ts:109:32:109:37 | number | number | +| tst.ts:109:39:109:39 | - | any | +| tst.ts:109:42:109:47 | number | number | +| tst.ts:110:19:110:25 | `1-2-3` | "1-2-3" | +| tst.ts:110:19:110:25 | `1-2-3` | any | +| tst.ts:111:22:111:27 | number | number | +| tst.ts:111:29:111:32 | -2-3 | any | +| tst.ts:117:20:117:25 | number | number | +| tst.ts:121:23:121:28 | number | number | | type_alias.ts:1:6:1:6 | B | boolean | | type_alias.ts:1:10:1:16 | boolean | boolean | | type_alias.ts:3:8:3:8 | B | boolean | @@ -360,6 +441,7 @@ referenceDefinition | Color.red | type_definitions.ts:14:3:14:5 | red | | E | type_definition_objects.ts:6:8:6:16 | enum E {} | | EnumWithOneMember | type_definitions.ts:18:26:18:31 | member | +| Foo | tst.ts:116:3:129:3 | class F ... }\\n } | | HasArea | tst.ts:58:1:60:1 | interfa ... mber;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | @@ -367,6 +449,11 @@ referenceDefinition | MyUnion | tst.ts:65:1:65:54 | type My ... true}; | | MyUnion2 | tst.ts:68:1:68:49 | type My ... true}; | | NonAbstractDummy | tst.ts:54:1:56:1 | interfa ... mber;\\n} | +| Sub | tst.ts:97:3:101:3 | class S ... }\\n } | +| Super | tst.ts:91:3:95:3 | class S ... }\\n } | +| Super | tst.ts:91:3:95:3 | class S ... }\\n } | +| Thing | tst.ts:78:10:88:3 | class T ... }\\n } | +| ThingI | tst.ts:73:3:76:3 | interfa ... n);\\n } | | ValueOrArray | type_alias.ts:5:1:5:50 | type Va ... ay>; | | ValueOrArray | type_alias.ts:5:1:5:50 | type Va ... ay>; | | VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts index 68c4ca6ebdd..389770984fd 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts @@ -66,4 +66,65 @@ type MyUnion = {myUnion: true} | {stillMyUnion: true}; let union1: MyUnion = {myUnion: true}; type MyUnion2 = MyUnion | {yetAnotherType: true}; -let union2: MyUnion2 = {yetAnotherType: true}; \ No newline at end of file +let union2: MyUnion2 = {yetAnotherType: true}; + +module TS43 { + // TypeScript 4.3 setter/getter types + interface ThingI { + get size(): number + set size(value: number | string | boolean); + } + + export class Thing implements ThingI { + #size = 0; + + get size(): number { + return this.#size; + } + + set size(value: string | number | boolean) { + this.#size = Number(value); + } + } + + // overrides + class Super { + random(): number { + return 4; + } + } + + class Sub extends Super { + override random(): number { + return super.random() * 10; + } + } + + // inference of template strings. + function bar(s: string): `hello ${string}` { + // Previously an error, now works! + return `hello ${s}`; + } + + declare let s1: `${number}-${number}-${number}`; + declare let s2: `1-2-3`; + declare let s3: `${number}-2-3`; + s1 = s2; + s1 = s3; + + // private methods + class Foo { + #someMethod(): number { + return 42; + } + + get #someValue(): number { + return 100; + } + + publicMethod() { + this.#someMethod(); + return this.#someValue; + } + } +} \ No newline at end of file From 85bd8f1020768178915853df4b2f76622cd2d845 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 31 May 2021 13:08:52 +0200 Subject: [PATCH 064/272] add change-note for TypeScript 4.3 --- javascript/change-notes/2021-05-31-typescript-4.3.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 javascript/change-notes/2021-05-31-typescript-4.3.md diff --git a/javascript/change-notes/2021-05-31-typescript-4.3.md b/javascript/change-notes/2021-05-31-typescript-4.3.md new file mode 100644 index 00000000000..21960a98dce --- /dev/null +++ b/javascript/change-notes/2021-05-31-typescript-4.3.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* TypeScript 4.3 is now supported. From 8dc1451d42f2eefce0e62ee5a7a1b198272abad3 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Tue, 1 Jun 2021 12:16:09 +0300 Subject: [PATCH 065/272] Better recommendation in UnsafeDeserializationRmi.qhelp Co-authored-by: Chris Smowton --- .../Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp index ea06f315cc4..02ee7d7dab1 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-502/UnsafeDeserializationRmi.qhelp @@ -13,7 +13,7 @@ In the worst case, it results in remote code execution.

    -Use only strings and primitive types in parameters of remote objects. +Use only strings and primitive types for parameters of remotely invokable methods.

    Set a filter for incoming serialized data by wrapping remote objects using either UnicastRemoteObject.exportObject(Remote, int, ObjectInputFilter) From 1001dd84e65a7a9dfbb0be8a27bdbb3dc3f18e9d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 19 May 2021 10:45:02 +0200 Subject: [PATCH 066/272] Java: Switch array steps and one containerstep. --- .../java/dataflow/internal/ContainerFlow.qll | 43 +++++++++++++++++++ .../dataflow/internal/DataFlowPrivate.qll | 11 ++++- .../java/dataflow/internal/DataFlowUtil.qll | 2 + .../internal/FlowSummaryImplSpecific.qll | 6 +++ .../dataflow/internal/TaintTrackingUtil.qll | 22 ---------- 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll index 5425471ca44..52a9b1704dd 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -1,6 +1,8 @@ import java import semmle.code.java.Collections import semmle.code.java.Maps +private import semmle.code.java.dataflow.SSA +private import DataFlowUtil private class EntryType extends RefType { EntryType() { @@ -426,3 +428,44 @@ predicate containerStep(Expr n1, Expr n2) { containerReturnValueStep(n1, n2) or containerUpdateStep(n1, n2) } + +predicate arrayStoreStep(Node node1, Node node2) { + exists(Argument arg | + node1.asExpr() = arg and + arg.isVararg() and + node2.(ImplicitVarargsArray).getCall() = arg.getCall() + ) + or + node2.asExpr().(ArrayInit).getAnInit() = node1.asExpr() + or + exists(Assignment assign | assign.getSource() = node1.asExpr() | + node2.(PostUpdateNode).getPreUpdateNode().asExpr() = assign.getDest().(ArrayAccess).getArray() + ) +} + +private predicate enhancedForStmtStep(Node node1, Node node2, Type containerType) { + exists(EnhancedForStmt for, Expr e, SsaExplicitUpdate v | + for.getExpr() = e and + node1.asExpr() = e and + containerType = e.getType() and + v.getDefiningExpr() = for.getVariable() and + v.getAFirstUse() = node2.asExpr() + ) +} + +predicate arrayReadStep(Node node1, Node node2, Type elemType) { + exists(ArrayAccess aa | + aa.getArray() = node1.asExpr() and + aa.getType() = elemType and + node2.asExpr() = aa + ) + or + exists(Array arr | + enhancedForStmtStep(node1, node2, arr) and + arr.getComponentType() = elemType + ) +} + +predicate collectionReadStep(Node node1, Node node2) { + enhancedForStmtStep(node1, node2, any(Type t | not t instanceof Array)) +} diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index e3ab07fce1f..54c4b775272 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -4,6 +4,7 @@ private import DataFlowImplCommon private import DataFlowDispatch private import semmle.code.java.controlflow.Guards private import semmle.code.java.dataflow.SSA +private import ContainerFlow private import FlowSummaryImpl as FlowSummaryImpl import DataFlowNodes::Private @@ -137,13 +138,15 @@ class MapValueContent extends Content, TMapValueContent { * Thus, `node2` references an object with a field `f` that contains the * value of `node1`. */ -predicate storeStep(Node node1, Content f, PostUpdateNode node2) { +predicate storeStep(Node node1, Content f, Node node2) { exists(FieldAccess fa | instanceFieldAssign(node1.asExpr(), fa) and - node2.getPreUpdateNode() = getFieldQualifier(fa) and + node2.(PostUpdateNode).getPreUpdateNode() = getFieldQualifier(fa) and f.(FieldContent).getField() = fa.getField() ) or + f instanceof ArrayContent and arrayStoreStep(node1, node2) + or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, f, node2) } @@ -171,6 +174,10 @@ predicate readStep(Node node1, Content f, Node node2) { node2.asExpr() = get ) or + f instanceof ArrayContent and arrayReadStep(node1, node2, _) + or + f instanceof CollectionContent and collectionReadStep(node1, node2) + or FlowSummaryImpl::Private::Steps::summaryReadStep(node1, f, node2) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll index e25ab24cfbb..e3ee2ddd595 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -144,6 +144,8 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { or node2.asExpr().(AssignExpr).getSource() = node1.asExpr() or + node2.asExpr().(ArrayCreationExpr).getInit() = node1.asExpr() + or exists(MethodAccess ma, ValuePreservingMethod m, int argNo | ma.getCallee().getSourceDeclaration() = m and m.returnsValue(argNo) | diff --git a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index dae0571f0fa..6f127c4b92d 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -30,6 +30,12 @@ DataFlowType getContentType(Content c) { or c instanceof ArrayContent and result instanceof TypeObject + or + c instanceof MapKeyContent and + result instanceof TypeObject + or + c instanceof MapValueContent and + result instanceof TypeObject } /** Gets the return type of kind `rk` for callable `c`. */ diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 8c514e357d2..339e0f05e1e 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -60,12 +60,6 @@ private module Cached { localAdditionalTaintUpdateStep(src.asExpr(), sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) or - exists(Argument arg | - src.asExpr() = arg and - arg.isVararg() and - sink.(DataFlow::ImplicitVarargsArray).getCall() = arg.getCall() - ) - or FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) } @@ -103,20 +97,8 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) { or sink.(AssignAddExpr).getSource() = src and sink.getType() instanceof TypeString or - sink.(ArrayCreationExpr).getInit() = src - or - sink.(ArrayInit).getAnInit() = src - or - sink.(ArrayAccess).getArray() = src - or sink.(LogicExpr).getAnOperand() = src or - exists(EnhancedForStmt for, SsaExplicitUpdate v | - for.getExpr() = src and - v.getDefiningExpr() = for.getVariable() and - v.getAFirstUse() = sink - ) - or containerReturnValueStep(src, sink) or constructorStep(src, sink) @@ -141,10 +123,6 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) { * This is restricted to cases where the step updates the value of `sink`. */ private predicate localAdditionalTaintUpdateStep(Expr src, Expr sink) { - exists(Assignment assign | assign.getSource() = src | - sink = assign.getDest().(ArrayAccess).getArray() - ) - or containerUpdateStep(src, sink) or qualifierToArgumentStep(src, sink) From ffd52bb673f9cdcc0237bcfb7e93098a6f94110d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 22 Apr 2021 11:00:31 +0200 Subject: [PATCH 067/272] Java: Fix bug in matching generic signatures. --- java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 33a146d07fe..8aa8447f7fb 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -561,7 +561,7 @@ private RefType interpretType(string namespace, string type, boolean subtypes) { private string paramsStringPart(Callable c, int i) { i = -1 and result = "(" or - exists(int n, string p | c.getParameterType(n).toString() = p | + exists(int n, string p | c.getParameterType(n).getErasure().toString() = p | i = 2 * n and result = p or i = 2 * n - 1 and result = "," and n != 0 From 3b6cef4f7464a9396483a0022503c82f92ed04e3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 9 Apr 2021 15:32:28 +0200 Subject: [PATCH 068/272] Java: Add container flow models. --- .../code/java/dataflow/ExternalFlow.qll | 1 + .../java/dataflow/internal/ContainerFlow.qll | 281 ++++++++++++++++++ 2 files changed, 282 insertions(+) diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 8aa8447f7fb..34fa8d66dd3 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -74,6 +74,7 @@ private import FlowSummary * ensuring that they are visible to the taint tracking / data flow library. */ private module Frameworks { + private import internal.ContainerFlow private import semmle.code.java.frameworks.ApacheHttp private import semmle.code.java.frameworks.apache.Lang private import semmle.code.java.frameworks.guava.Guava diff --git a/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll index 52a9b1704dd..667ae024b37 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -3,6 +3,7 @@ import semmle.code.java.Collections import semmle.code.java.Maps private import semmle.code.java.dataflow.SSA private import DataFlowUtil +private import semmle.code.java.dataflow.ExternalFlow private class EntryType extends RefType { EntryType() { @@ -90,6 +91,286 @@ class ContainerType extends RefType { } } +private class ContainerFlowSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + "java.util;Map<>$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map<>$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map<>$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value", + "java.lang;Iterable;true;iterator;();;Element of Argument[-1];Element of ReturnValue;value", + "java.lang;Iterable;true;spliterator;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Iterator;true;next;;;Element of Argument[-1];ReturnValue;value", + "java.util;ListIterator;true;previous;;;Element of Argument[-1];ReturnValue;value", + "java.util;ListIterator;true;add;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;ListIterator;true;set;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Enumeration;true;asIterator;;;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Enumeration;true;nextElement;;;Element of Argument[-1];ReturnValue;value", + "java.util;Map;true;computeIfAbsent;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];ReturnValue;value", + "java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];MapValue of Argument[-1];value", + "java.util;Map;true;entrySet;;;MapValue of Argument[-1];MapValue of Element of ReturnValue;value", + "java.util;Map;true;entrySet;;;MapKey of Argument[-1];MapKey of Element of ReturnValue;value", + "java.util;Map;true;get;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;getOrDefault;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;getOrDefault;;;Argument[1];ReturnValue;value", + "java.util;Map;true;put;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;put;;;Argument[0];MapKey of Argument[-1];value", + "java.util;Map;true;put;;;Argument[1];MapValue of Argument[-1];value", + "java.util;Map;true;putIfAbsent;;;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;putIfAbsent;;;Argument[0];MapKey of Argument[-1];value", + "java.util;Map;true;putIfAbsent;;;Argument[1];MapValue of Argument[-1];value", + "java.util;Map;true;remove;(Object);;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;replace;(Object,Object);;MapValue of Argument[-1];ReturnValue;value", + "java.util;Map;true;replace;(Object,Object);;Argument[0];MapKey of Argument[-1];value", + "java.util;Map;true;replace;(Object,Object);;Argument[1];MapValue of Argument[-1];value", + "java.util;Map;true;replace;(Object,Object,Object);;Argument[0];MapKey of Argument[-1];value", + "java.util;Map;true;replace;(Object,Object,Object);;Argument[2];MapValue of Argument[-1];value", + "java.util;Map;true;keySet;();;MapKey of Argument[-1];Element of ReturnValue;value", + "java.util;Map;true;values;();;MapValue of Argument[-1];Element of ReturnValue;value", + "java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];MapValue of Argument[-1];value", + "java.util;Map;true;putAll;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value", + "java.util;Map;true;putAll;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value", + "java.util;Collection;true;parallelStream;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Collection;true;stream;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value", + "java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of Argument[0];value", + "java.util;Collection;true;add;;;Argument[0];Element of Argument[-1];value", + "java.util;Collection;true;addAll;;;Element of Argument[0];Element of Argument[-1];value", + "java.util;List;true;get;(int);;Element of Argument[-1];ReturnValue;value", + "java.util;List;true;listIterator;;;Element of Argument[-1];Element of ReturnValue;value", + "java.util;List;true;remove;(int);;Element of Argument[-1];ReturnValue;value", + "java.util;List;true;set;(int,Object);;Element of Argument[-1];ReturnValue;value", + "java.util;List;true;set;(int,Object);;Argument[1];Element of Argument[-1];value", + "java.util;List;true;subList;;;Element of Argument[-1];Element of ReturnValue;value", + "java.util;List;true;add;(int,Object);;Argument[1];Element of Argument[-1];value", + "java.util;List;true;addAll;(int,Collection);;Element of Argument[1];Element of Argument[-1];value", + "java.util;Vector;true;elementAt;(int);;Element of Argument[-1];ReturnValue;value", + "java.util;Vector;true;elements;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Vector;true;firstElement;();;Element of Argument[-1];ReturnValue;value", + "java.util;Vector;true;lastElement;();;Element of Argument[-1];ReturnValue;value", + "java.util;Vector;true;addElement;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Vector;true;insertElementAt;(Object,int);;Argument[0];Element of Argument[-1];value", + "java.util;Vector;true;setElementAt;(Object,int);;Argument[0];Element of Argument[-1];value", + "java.util;Vector;true;copyInto;(Object[]);;Element of Argument[-1];ArrayElement of Argument[0];value", + "java.util;Stack;true;peek;();;Element of Argument[-1];ReturnValue;value", + "java.util;Stack;true;pop;();;Element of Argument[-1];ReturnValue;value", + "java.util;Stack;true;push;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Queue;true;element;();;Element of Argument[-1];ReturnValue;value", + "java.util;Queue;true;peek;();;Element of Argument[-1];ReturnValue;value", + "java.util;Queue;true;poll;();;Element of Argument[-1];ReturnValue;value", + "java.util;Queue;true;remove;();;Element of Argument[-1];ReturnValue;value", + "java.util;Queue;true;offer;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Deque;true;descendingIterator;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Deque;true;getFirst;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;getLast;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;peekFirst;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;peekLast;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;pollFirst;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;pollLast;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;pop;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;removeFirst;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;removeLast;();;Element of Argument[-1];ReturnValue;value", + "java.util;Deque;true;push;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Deque;true;offerLast;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Deque;true;offerFirst;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Deque;true;addLast;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;Deque;true;addFirst;(Object);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value", + "java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value", + "java.util.concurrent;BlockingDeque;true;takeFirst;();;Element of Argument[-1];ReturnValue;value", + "java.util.concurrent;BlockingDeque;true;takeLast;();;Element of Argument[-1];ReturnValue;value", + "java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value", + "java.util.concurrent;BlockingQueue;true;take;();;Element of Argument[-1];ReturnValue;value", + "java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingQueue;true;put;(Object);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingDeque;true;offerLast;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingDeque;true;offerFirst;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingDeque;true;putLast;(Object);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingDeque;true;putFirst;(Object);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Element of Argument[-1];Element of Argument[0];value", + "java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Element of Argument[-1];Element of Argument[0];value", + "java.util.concurrent;ConcurrentHashMap;true;elements;();;MapValue of Argument[-1];Element of ReturnValue;value", + "java.util;Dictionary;true;elements;();;MapValue of Argument[-1];Element of ReturnValue;value", + "java.util;Dictionary;true;get;(Object);;MapValue of Argument[-1];ReturnValue;value", + "java.util;Dictionary;true;put;(Object,Object);;MapValue of Argument[-1];ReturnValue;value", + "java.util;Dictionary;true;put;(Object,Object);;Argument[0];MapKey of Argument[-1];value", + "java.util;Dictionary;true;put;(Object,Object);;Argument[1];MapValue of Argument[-1];value", + "java.util;Dictionary;true;remove;(Object);;MapValue of Argument[-1];ReturnValue;value", + "java.util;NavigableMap;true;ceilingEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;ceilingEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;descendingMap;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;descendingMap;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;firstEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;firstEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;floorEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;floorEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;headMap;(Object,boolean);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;headMap;(Object,boolean);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;higherEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;higherEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;lastEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;lastEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;lowerEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;lowerEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;pollFirstEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;pollFirstEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;pollLastEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;pollLastEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableMap;true;tailMap;(Object,boolean);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;NavigableMap;true;tailMap;(Object,boolean);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;NavigableSet;true;ceiling;(Object);;Element of Argument[-1];ReturnValue;value", + "java.util;NavigableSet;true;descendingIterator;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;NavigableSet;true;descendingSet;();;Element of Argument[-1];Element of ReturnValue;value", + "java.util;NavigableSet;true;floor;(Object);;Element of Argument[-1];ReturnValue;value", + "java.util;NavigableSet;true;headSet;(Object,boolean);;Element of Argument[-1];Element of ReturnValue;value", + "java.util;NavigableSet;true;higher;(Object);;Element of Argument[-1];ReturnValue;value", + "java.util;NavigableSet;true;lower;(Object);;Element of Argument[-1];ReturnValue;value", + "java.util;NavigableSet;true;pollFirst;();;Element of Argument[-1];ReturnValue;value", + "java.util;NavigableSet;true;pollLast;();;Element of Argument[-1];ReturnValue;value", + "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Element of Argument[-1];Element of ReturnValue;value", + "java.util;NavigableSet;true;tailSet;(Object,boolean);;Element of Argument[-1];Element of ReturnValue;value", + "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint", + "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint", + "java.util;SortedMap;true;headMap;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;SortedMap;true;headMap;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;SortedMap;true;subMap;(Object,Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;SortedMap;true;subMap;(Object,Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;SortedMap;true;tailMap;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + "java.util;SortedMap;true;tailMap;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + "java.util;SortedSet;true;first;();;Element of Argument[-1];ReturnValue;value", + "java.util;SortedSet;true;headSet;(Object);;Element of Argument[-1];Element of ReturnValue;value", + "java.util;SortedSet;true;last;();;Element of Argument[-1];ReturnValue;value", + "java.util;SortedSet;true;subSet;(Object,Object);;Element of Argument[-1];Element of ReturnValue;value", + "java.util;SortedSet;true;tailSet;(Object);;Element of Argument[-1];Element of ReturnValue;value", + "java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;TransferQueue;true;transfer;(Object);;Argument[0];Element of Argument[-1];value", + "java.util.concurrent;TransferQueue;true;tryTransfer;(Object);;Argument[0];Element of Argument[-1];value", + "java.util;List;false;copyOf;(Collection);;Element of Argument[0];Element of ReturnValue;value", + "java.util;List;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value", + "java.util;List;false;of;(Object);;Argument[0];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object);;Argument[0..1];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object);;Argument[0..2];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object);;Argument[0..3];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];Element of ReturnValue;value", + "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];Element of ReturnValue;value", + "java.util;Map;false;copyOf;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Map;false;copyOf;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Map;false;entry;(Object,Object);;Argument[0];MapKey of ReturnValue;value", + "java.util;Map;false;entry;(Object,Object);;Argument[1];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[0];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[1];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[2];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[3];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[4];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[5];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[6];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[7];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[8];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[9];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[10];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[11];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[12];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[13];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[14];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[15];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[16];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[17];MapValue of ReturnValue;value", + "java.util;Map;false;of;;;Argument[18];MapKey of ReturnValue;value", + "java.util;Map;false;of;;;Argument[19];MapValue of ReturnValue;value", + "java.util;Map;false;ofEntries;;;MapKey of ArrayElement of Argument[0];MapKey of ReturnValue;value", + "java.util;Map;false;ofEntries;;;MapValue of ArrayElement of Argument[0];MapValue of ReturnValue;value", + "java.util;Set;false;copyOf;(Collection);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Set;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value", + "java.util;Set;false;of;(Object);;Argument[0];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object);;Argument[0..1];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object);;Argument[0..2];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[0..3];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];Element of ReturnValue;value", + "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];Element of ReturnValue;value", + "java.util;Arrays;false;stream;;;ArrayElement of Argument[0];Element of ReturnValue;value", + "java.util;Arrays;false;spliterator;;;ArrayElement of Argument[0];Element of ReturnValue;value", + "java.util;Arrays;false;copyOfRange;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value", + "java.util;Arrays;false;copyOf;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value", + "java.util;Collections;false;list;(Enumeration);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;enumeration;(Collection);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;nCopies;(int,Object);;Argument[1];Element of ReturnValue;value", + "java.util;Collections;false;singletonMap;(Object,Object);;Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;singletonMap;(Object,Object);;Argument[1];MapValue of ReturnValue;value", + "java.util;Collections;false;singletonList;(Object);;Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;singleton;(Object);;Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;checkedMap;(Map,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;checkedMap;(Map,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;checkedList;(List,Class);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;checkedSet;(Set,Class);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;checkedCollection;(Collection,Class);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;synchronizedMap;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;synchronizedMap;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;synchronizedList;(List);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;synchronizedSet;(Set);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;synchronizedCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;unmodifiableMap;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value", + "java.util;Collections;false;unmodifiableMap;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value", + "java.util;Collections;false;unmodifiableList;(List);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;unmodifiableSet;(Set);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;unmodifiableCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;max;;;Element of Argument[0];ReturnValue;value", + "java.util;Collections;false;min;;;Element of Argument[0];ReturnValue;value", + "java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(Object[],Object);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(float[],int,int,float);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(float[],float);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(double[],int,int,double);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(double[],double);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(boolean[],int,int,boolean);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(boolean[],boolean);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(byte[],int,int,byte);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(byte[],byte);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(char[],int,int,char);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(char[],char);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(short[],int,int,short);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(short[],short);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(int[],int,int,int);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(int[],int);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(long[],int,int,long);;Argument[3];ArrayElement of Argument[0];value", + "java.util;Arrays;false;fill;(long[],long);;Argument[1];ArrayElement of Argument[0];value", + "java.util;Collections;false;replaceAll;(List,Object,Object);;Argument[2];Element of Argument[0];value", + "java.util;Collections;false;copy;(List,List);;Element of Argument[1];Element of Argument[0];value", + "java.util;Collections;false;fill;(List,Object);;Argument[1];Element of Argument[0];value", + "java.util;Arrays;false;asList;;;ArrayElement of Argument[0];Element of ReturnValue;value", + "java.util;Collections;false;addAll;(Collection,Object[]);;ArrayElement of Argument[1];Element of Argument[0];value" + ] + } +} + private predicate taintPreservingQualifierToMethod(Method m) { // java.util.Map.Entry m.getDeclaringType() instanceof EntryType and From 9e313d0cf6817201b96181463bc01ecc13cb1ead Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 22 Apr 2021 16:57:41 +0200 Subject: [PATCH 069/272] Java: Remove container taint steps. --- .../semmle/code/java/dataflow/internal/TaintTrackingUtil.qll | 4 ---- 1 file changed, 4 deletions(-) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 339e0f05e1e..079d61809db 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -99,8 +99,6 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) { or sink.(LogicExpr).getAnOperand() = src or - containerReturnValueStep(src, sink) - or constructorStep(src, sink) or qualifierToMethodStep(src, sink) @@ -123,8 +121,6 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) { * This is restricted to cases where the step updates the value of `sink`. */ private predicate localAdditionalTaintUpdateStep(Expr src, Expr sink) { - containerUpdateStep(src, sink) - or qualifierToArgumentStep(src, sink) or argToArgStep(src, sink) From 3f538e7fac175e8d2778586f4da161105f745962 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 4 May 2021 10:48:28 +0200 Subject: [PATCH 070/272] Java: Update some models. --- .../code/java/frameworks/ApacheHttp.qll | 19 ++-- .../code/java/frameworks/apache/Lang.qll | 107 +++++++++++------- .../code/java/frameworks/guava/Base.qll | 8 +- .../semmle/code/java/frameworks/guava/IO.qll | 8 +- 4 files changed, 93 insertions(+), 49 deletions(-) diff --git a/java/ql/src/semmle/code/java/frameworks/ApacheHttp.qll b/java/ql/src/semmle/code/java/frameworks/ApacheHttp.qll index 8378f1e7260..80cb589e6f2 100644 --- a/java/ql/src/semmle/code/java/frameworks/ApacheHttp.qll +++ b/java/ql/src/semmle/code/java/frameworks/ApacheHttp.qll @@ -165,14 +165,17 @@ private class ApacheHttpFlowStep extends SummaryModelCsv { "org.apache.http.util;EncodingUtils;true;getAsciiString;;;Argument[0];ReturnValue;taint", "org.apache.http.util;EncodingUtils;true;getBytes;(String,String);;Argument[0];ReturnValue;taint", "org.apache.http.util;EncodingUtils;true;getString;;;Argument[0];ReturnValue;taint", - "org.apache.http.util;Args;true;containsNoBlanks;(T,String);;Argument[0];ReturnValue;value", - "org.apache.http.util;Args;true;notNull;(T,String);;Argument[0];ReturnValue;value", - "org.apache.http.util;Args;true;notEmpty;(T,String);;Argument[0];ReturnValue;value", - "org.apache.http.util;Args;true;notBlank;(T,String);;Argument[0];ReturnValue;value", - "org.apache.hc.core5.util;Args;true;containsNoBlanks;(T,String);;Argument[0];ReturnValue;value", - "org.apache.hc.core5.util;Args;true;notNull;(T,String);;Argument[0];ReturnValue;value", - "org.apache.hc.core5.util;Args;true;notEmpty;(T,String);;Argument[0];ReturnValue;value", - "org.apache.hc.core5.util;Args;true;notBlank;(T,String);;Argument[0];ReturnValue;value", + "org.apache.http.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value", + "org.apache.http.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value", + "org.apache.http.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value", + "org.apache.http.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value", + "org.apache.http.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value", + "org.apache.hc.core5.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value", + "org.apache.hc.core5.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value", + "org.apache.hc.core5.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value", + "org.apache.hc.core5.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value", + "org.apache.hc.core5.util;Args;true;notEmpty;(Object,String);;Argument[0];ReturnValue;value", + "org.apache.hc.core5.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value", "org.apache.hc.core5.http.io.entity;HttpEntities;true;create;;;Argument[0];ReturnValue;taint", "org.apache.hc.core5.http.io.entity;HttpEntities;true;createGzipped;;;Argument[0];ReturnValue;taint", "org.apache.hc.core5.http.io.entity;HttpEntities;true;createUrlEncoded;;;Argument[0];ReturnValue;taint", diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index 670014e0f8f..ab411c5ce48 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -94,29 +94,33 @@ private class ApacheStringUtilsModel extends SummaryModelCsv { "org.apache.commons.lang3;StringUtils;false;defaultString;;;Argument[0..1];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;deleteWhitespace;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;difference;;;Argument[0..1];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;firstNonBlank;;;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;firstNonEmpty;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;firstNonBlank;;;ArrayElement of Argument[0];ReturnValue;value", + "org.apache.commons.lang3;StringUtils;false;firstNonEmpty;;;ArrayElement of Argument[0];ReturnValue;value", "org.apache.commons.lang3;StringUtils;false;getBytes;;;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;getCommonPrefix;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;getCommonPrefix;;;ArrayElement of Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;getDigits;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;getIfBlank;;;Argument[0..1];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;getIfEmpty;;;Argument[0..1];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;join;(char[],char);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;join;(char[],char,int,int);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,char);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[0..1];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[]);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char,int,int);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[0..1];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,char);;Element of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Element of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[1];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[]);;ArrayElement of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char);;ArrayElement of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char,int,int);;ArrayElement of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;ArrayElement of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[1];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;ArrayElement of Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[1];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,char);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[0..1];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,char,int,int);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,char);;Element of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Element of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[1];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,char,int,int);;Element of Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Element of Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[1];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[0..1];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;joinWith;;;ArrayElement of Argument[1];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;left;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;leftPad;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;leftPad;;;Argument[0];ReturnValue;taint", @@ -148,9 +152,9 @@ private class ApacheStringUtilsModel extends SummaryModelCsv { "org.apache.commons.lang3;StringUtils;false;replaceChars;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;replaceChars;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[2];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;replaceEach;;;ArrayElement of Argument[2];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[2];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;ArrayElement of Argument[2];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[2];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;replaceIgnoreCase;;;Argument[0];ReturnValue;taint", @@ -182,7 +186,7 @@ private class ApacheStringUtilsModel extends SummaryModelCsv { "org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;stripAccents;;;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3;StringUtils;false;stripAll;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3;StringUtils;false;stripAll;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;stripEnd;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;stripStart;;;Argument[0];ReturnValue;taint", "org.apache.commons.lang3;StringUtils;false;stripToEmpty;;;Argument[0];ReturnValue;taint", @@ -229,7 +233,8 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint", @@ -238,7 +243,9 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.lang3.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterable);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterator);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Object[]);;ArrayElement of Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint", @@ -249,14 +256,18 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[0..1];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Object[],String);;ArrayElement of Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint", @@ -296,7 +307,8 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint", @@ -305,7 +317,9 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;(org.apache.commons.text.StrBuilder);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendAll;(Iterable);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendAll;(Iterator);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendAll;(Object[]);;ArrayElement of Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint", @@ -316,14 +330,18 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[0..1];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Object[],String);;ArrayElement of Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint", @@ -364,7 +382,8 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint", @@ -373,7 +392,9 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.text;TextStringBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;(org.apache.commons.text.TextStringBuilder);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterable);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterator);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendAll;(Object[]);;ArrayElement of Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint", @@ -384,14 +405,18 @@ private class ApacheStrBuilderModel extends SummaryModelCsv { "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;TextStringBuilder;false;appendTo;;;Argument[-1];Argument[0];taint", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[0..1];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterable,String);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterator,String);;Element of Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Object[],String);;ArrayElement of Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint", + "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint", "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint", @@ -525,9 +550,9 @@ private class ApacheStrLookupModel extends SummaryModelCsv { row = [ "org.apache.commons.lang3.text;StrLookup;false;lookup;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.lang3.text;StrLookup;false;mapLookup;;;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.text;StrLookup;false;mapLookup;;;MapValue of Argument[0];ReturnValue;taint", "org.apache.commons.text.lookup;StringLookup;true;lookup;;;Argument[-1];ReturnValue;taint", - "org.apache.commons.text.lookup;StringLookupFactory;false;mapStringLookup;;;Argument[0];ReturnValue;taint" + "org.apache.commons.text.lookup;StringLookupFactory;false;mapStringLookup;;;MapValue of Argument[0];ReturnValue;taint" ] } } @@ -540,6 +565,7 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv { row = [ "org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;Argument[0];Argument[-1];taint", + "org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;MapValue of Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint", @@ -552,10 +578,12 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv { "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0..1];ReturnValue;taint", + "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;MapValue of Argument[1];ReturnValue;taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1];ReturnValue;taint", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0..1];ReturnValue;taint", + "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;MapValue of Argument[1];ReturnValue;taint", + "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint", + "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;MapValue of Argument[1];ReturnValue;taint", "org.apache.commons.lang3.text;StrSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder);;Argument[-1];Argument[0];taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuffer);;Argument[-1];Argument[0];taint", @@ -564,6 +592,7 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv { "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuilder,int,int);;Argument[-1];Argument[0];taint", "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[-1];Argument[0];taint", "org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;Argument[0];Argument[-1];taint", + "org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;MapValue of Argument[0];Argument[-1];taint", "org.apache.commons.text;StringSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint", @@ -574,10 +603,12 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv { "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer);;Argument[0];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0..1];ReturnValue;taint", + "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint", + "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;MapValue of Argument[1];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1];ReturnValue;taint", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0..1];ReturnValue;taint", + "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;MapValue of Argument[1];ReturnValue;taint", + "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint", + "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;MapValue of Argument[1];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder);;Argument[0];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder,int,int);;Argument[0];ReturnValue;taint", "org.apache.commons.text;StringSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint", diff --git a/java/ql/src/semmle/code/java/frameworks/guava/Base.qll b/java/ql/src/semmle/code/java/frameworks/guava/Base.qll index 04a97f79f53..fc1ee0e6cb7 100644 --- a/java/ql/src/semmle/code/java/frameworks/guava/Base.qll +++ b/java/ql/src/semmle/code/java/frameworks/guava/Base.qll @@ -30,7 +30,13 @@ private class GuavaBaseCsv extends SummaryModelCsv { "com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint", "com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[1];Argument[0];taint", "com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[0];ReturnValue;value", - "com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1..0];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;MapKey of Element of Argument[0];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;MapValue of Element of Argument[0];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;MapKey of Element of Argument[0];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;MapValue of Element of Argument[0];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;(Map);;MapKey of Argument[0];ReturnValue;taint", + "com.google.common.base;Joiner$MapJoiner;false;join;(Map);;MapValue of Argument[0];ReturnValue;taint", "com.google.common.base;Splitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint", "com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[0];ReturnValue;taint", "com.google.common.base;Splitter;false;splitToStream;(CharSequence);;Argument[0];ReturnValue;taint", diff --git a/java/ql/src/semmle/code/java/frameworks/guava/IO.qll b/java/ql/src/semmle/code/java/frameworks/guava/IO.qll index fac9ab9d48d..305b4fbcfb7 100644 --- a/java/ql/src/semmle/code/java/frameworks/guava/IO.qll +++ b/java/ql/src/semmle/code/java/frameworks/guava/IO.qll @@ -24,7 +24,9 @@ private class GuavaIoCsv extends SummaryModelCsv { "com.google.common.io;BaseEncoding;true;omitPadding;();;Argument[-1];ReturnValue;taint", "com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[-1];ReturnValue;taint", "com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[-1];ReturnValue;taint", - "com.google.common.io;ByteSource;true;concat;;;Argument[0];ReturnValue;taint", + "com.google.common.io;ByteSource;true;concat;(ByteSource[]);;ArrayElement of Argument[0];ReturnValue;taint", + "com.google.common.io;ByteSource;true;concat;(Iterable);;Element of Argument[0];ReturnValue;taint", + "com.google.common.io;ByteSource;true;concat;(Iterator);;Element of Argument[0];ReturnValue;taint", "com.google.common.io;ByteSource;true;copyTo;(OutputStream);;Argument[-1];Argument[0];taint", "com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint", "com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint", @@ -43,7 +45,9 @@ private class GuavaIoCsv extends SummaryModelCsv { "com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint", "com.google.common.io;ByteStreams;false;toByteArray;(InputStream);;Argument[0];ReturnValue;taint", "com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint", - "com.google.common.io;CharSource;true;concat;;;Argument[0];ReturnValue;taint", + "com.google.common.io;CharSource;true;concat;(CharSource[]);;ArrayElement of Argument[0];ReturnValue;taint", + "com.google.common.io;CharSource;true;concat;(Iterable);;Element of Argument[0];ReturnValue;taint", + "com.google.common.io;CharSource;true;concat;(Iterator);;Element of Argument[0];ReturnValue;taint", "com.google.common.io;CharSource;true;copyTo;(Appendable);;Argument[-1];Argument[0];taint", "com.google.common.io;CharSource;true;openStream;();;Argument[-1];ReturnValue;taint", "com.google.common.io;CharSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint", From 2f087e17cb1b328a87c2ea998bf1cdf4f052e663 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 5 May 2021 15:07:31 +0200 Subject: [PATCH 071/272] Java: Allow <> in types for now. --- java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 34fa8d66dd3..d4b2c917148 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -481,7 +481,7 @@ module CsvValidation { not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model." or - not type.regexpMatch("[a-zA-Z0-9_\\$]+") and + not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and msg = "Dubious type \"" + type + "\" in " + pred + " model." or not name.regexpMatch("[a-zA-Z0-9_]*") and From a40880af70524e581811eb87b40b9e3d00e27dd6 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 19 May 2021 10:45:54 +0200 Subject: [PATCH 072/272] Java: Add read-as-taint and config-dependent store-as-taint. --- .../dataflow/internal/TaintTrackingUtil.qll | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 079d61809db..719b89fbf2a 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -60,6 +60,17 @@ private module Cached { localAdditionalTaintUpdateStep(src.asExpr(), sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) or + exists(Content f | + readStep(src, f, sink) and + not sink.getTypeBound() instanceof PrimitiveType and + not sink.getTypeBound() instanceof BoxedType and + not sink.getTypeBound() instanceof NumberType + | + f instanceof ArrayContent or + f instanceof CollectionContent or + f instanceof MapValueContent + ) + or FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) } @@ -87,6 +98,81 @@ private module Cached { import Cached +private module StoreTaintSteps { + private import semmle.code.java.dataflow.TaintTracking + private import semmle.code.java.dataflow.TaintTracking2 + + private class StoreTaintConfig extends TaintTracking::Configuration { + StoreTaintConfig() { this instanceof TaintTracking::Configuration or none() } + + override predicate isSource(DataFlow::Node n) { none() } + + override predicate isSink(DataFlow::Node n) { none() } + + private predicate needsTaintStore(RefType container, Type elem, Content f) { + exists(DataFlow::Node arg | + (isSink(arg) or isAdditionalTaintStep(arg, _)) and + (arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and + arg.getType() = container + or + needsTaintStore(_, container, _) + | + container.(Array).getComponentType() = elem and + f instanceof ArrayContent + or + container.(CollectionType).getElementType() = elem and + f instanceof CollectionContent + or + container.(MapType).getValueType() = elem and + f instanceof MapValueContent + ) + } + + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(Content f, Type elem | + storeStep(node1, f, node2) and + needsTaintStore(_, elem, f) and + not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem)) + ) + } + } + + private class StoreTaintConfig2 extends TaintTracking2::Configuration { + StoreTaintConfig2() { this instanceof TaintTracking2::Configuration or none() } + + override predicate isSource(DataFlow::Node n) { none() } + + override predicate isSink(DataFlow::Node n) { none() } + + private predicate needsTaintStore(RefType container, Type elem, Content f) { + exists(DataFlow::Node arg | + (isSink(arg) or isAdditionalTaintStep(arg, _)) and + (arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and + arg.getType() = container + or + needsTaintStore(_, container, _) + | + container.(Array).getComponentType() = elem and + f instanceof ArrayContent + or + container.(CollectionType).getElementType() = elem and + f instanceof CollectionContent + or + container.(MapType).getValueType() = elem and + f instanceof MapValueContent + ) + } + + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(Content f, Type elem | + storeStep(node1, f, node2) and + needsTaintStore(_, elem, f) and + not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem)) + ) + } + } +} + /** * Holds if taint can flow in one local step from `src` to `sink` excluding * local data flow steps. That is, `src` and `sink` are likely to represent From 43d1b0ab273f5b5aea3942174839d60a2b1a3c9f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 4 May 2021 10:48:43 +0200 Subject: [PATCH 073/272] Java: Update qltests. --- ...ientSuppliedIpUsedInSecurityCheck.expected | 3 ++ .../CWE-522/InsecureLdapAuth.expected | 40 +++++++++++++++++++ .../CWE-598/SensitiveGetQuery.expected | 6 ++- .../CWE-927/SensitiveBroadcast.expected | 4 +- .../dataflow/collections/flow.expected | 3 -- .../library-tests/dataflow/getter/getter.ql | 7 +++- .../localAdditionalTaintStep.expected | 19 +++++---- .../localAdditionalTaintStep.ql | 28 ++++++++++++- .../dataflow/taint-ioutils/Test.java | 10 +++-- .../dataflow/taint-ioutils/dataFlow.expected | 8 +--- .../dataflow/taint/test.expected | 1 - .../apache-commons-lang3/ObjectUtilsTest.java | 30 +++++++------- .../frameworks/apache-commons-lang3/Test.java | 14 +++---- .../frameworks/guava/TestBase.java | 2 +- .../CWE-078/ExecTaintedLocal.expected | 6 ++- 15 files changed, 128 insertions(+), 53 deletions(-) diff --git a/java/ql/test/experimental/query-tests/security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected b/java/ql/test/experimental/query-tests/security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected index 5627f9541f1..160654628fe 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected @@ -1,7 +1,9 @@ edges | ClientSuppliedIpUsedInSecurityCheck.java:16:21:16:33 | getClientIP(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip | | ClientSuppliedIpUsedInSecurityCheck.java:24:21:24:33 | getClientIP(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:25:33:25:34 | ip | +| ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:34 | split(...) : String[] | | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | +| ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:34 | split(...) : String[] | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | ClientSuppliedIpUsedInSecurityCheck.java:16:21:16:33 | getClientIP(...) : String | | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | ClientSuppliedIpUsedInSecurityCheck.java:24:21:24:33 | getClientIP(...) : String | nodes @@ -10,6 +12,7 @@ nodes | ClientSuppliedIpUsedInSecurityCheck.java:24:21:24:33 | getClientIP(...) : String | semmle.label | getClientIP(...) : String | | ClientSuppliedIpUsedInSecurityCheck.java:25:33:25:34 | ip | semmle.label | ip | | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:34 | split(...) : String[] | semmle.label | split(...) : String[] | | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | semmle.label | ...[...] : String | #select | ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip | IP address spoofing might include code from $@. | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) | this user input | diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected index 863e8e55dcf..a3b12510626 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected @@ -1,52 +1,88 @@ edges +| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment | +| InsecureLdapAuth.java:15:3:15:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:20:49:20:59 | environment | +| InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | InsecureLdapAuth.java:15:3:15:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:20:49:20:59 | environment | +| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | | InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment | +| InsecureLdapAuth.java:29:3:29:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:34:49:34:59 | environment | +| InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | InsecureLdapAuth.java:29:3:29:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:34:49:34:59 | environment | | InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:48:49:48:59 | environment | +| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | | InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:63:49:63:59 | environment | +| InsecureLdapAuth.java:57:3:57:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | +| InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | InsecureLdapAuth.java:57:3:57:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | | InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | +| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | | InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:77:49:77:59 | environment | +| InsecureLdapAuth.java:72:3:72:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:77:49:77:59 | environment | +| InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | InsecureLdapAuth.java:72:3:72:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:91:49:91:59 | environment | +| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment | +| InsecureLdapAuth.java:100:3:100:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:105:59:105:69 | environment | +| InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | InsecureLdapAuth.java:100:3:100:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:105:59:105:69 | environment | +| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment | +| InsecureLdapAuth.java:115:3:115:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:120:49:120:59 | environment | +| InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | InsecureLdapAuth.java:115:3:115:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:120:49:120:59 | environment | | InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | | InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | | InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | +| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | | InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:142:50:142:60 | environment | | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | +| InsecureLdapAuth.java:140:3:140:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | +| InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | InsecureLdapAuth.java:140:3:140:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | +| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | | InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment | +| InsecureLdapAuth.java:151:3:151:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:153:50:153:60 | environment | +| InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | InsecureLdapAuth.java:151:3:151:13 | environment [post update] : Hashtable | | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:153:50:153:60 | environment | nodes | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:15:3:15:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | semmle.label | ... + ... : String | +| InsecureLdapAuth.java:29:3:29:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:48:49:48:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | semmle.label | "ldap://ad.your-server.com:636" : String | +| InsecureLdapAuth.java:57:3:57:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:72:3:72:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:77:49:77:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:91:49:91:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:100:3:100:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment | | InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment | | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:115:3:115:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment | | InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment | @@ -54,11 +90,15 @@ nodes | InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable | | InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | semmle.label | ... + ... : String | | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:140:3:140:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | | InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | | InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | | InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | semmle.label | ... + ... : String | +| InsecureLdapAuth.java:151:3:151:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | semmle.label | ldapUrl : String | | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | | InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment | | InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment | diff --git a/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected b/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected index 8e96a3ebfc0..2790e9f77d3 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected @@ -1,7 +1,9 @@ edges -| SensitiveGetQuery2.java:12:13:12:37 | getParameterMap(...) : Map | SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | +| SensitiveGetQuery2.java:12:13:12:37 | getParameterMap(...) : Map | SensitiveGetQuery2.java:14:30:14:32 | map : Map | | SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | SensitiveGetQuery2.java:15:29:15:36 | password | | SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | SensitiveGetQuery2.java:15:29:15:36 | password : Object | +| SensitiveGetQuery2.java:14:30:14:32 | map : Map | SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | +| SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | | SensitiveGetQuery2.java:15:29:15:36 | password : Object | SensitiveGetQuery2.java:18:40:18:54 | password : Object | | SensitiveGetQuery2.java:18:40:18:54 | password : Object | SensitiveGetQuery2.java:19:61:19:68 | password | | SensitiveGetQuery3.java:12:21:12:60 | getRequestParameter(...) : String | SensitiveGetQuery3.java:13:57:13:64 | password | @@ -15,6 +17,8 @@ edges nodes | SensitiveGetQuery2.java:12:13:12:37 | getParameterMap(...) : Map | semmle.label | getParameterMap(...) : Map | | SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | semmle.label | (...)... : Object | +| SensitiveGetQuery2.java:14:30:14:32 | map : Map | semmle.label | map : Map | +| SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | semmle.label | get(...) : Object | | SensitiveGetQuery2.java:15:29:15:36 | password | semmle.label | password | | SensitiveGetQuery2.java:15:29:15:36 | password : Object | semmle.label | password : Object | | SensitiveGetQuery2.java:18:40:18:54 | password : Object | semmle.label | password : Object | diff --git a/java/ql/test/experimental/query-tests/security/CWE-927/SensitiveBroadcast.expected b/java/ql/test/experimental/query-tests/security/CWE-927/SensitiveBroadcast.expected index 2b1384b845b..29482ca006d 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-927/SensitiveBroadcast.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-927/SensitiveBroadcast.expected @@ -3,7 +3,8 @@ edges | SensitiveBroadcast.java:13:41:13:52 | refreshToken : String | SensitiveBroadcast.java:14:31:14:36 | intent | | SensitiveBroadcast.java:25:32:25:39 | password : String | SensitiveBroadcast.java:26:31:26:36 | intent | | SensitiveBroadcast.java:36:35:36:39 | email : String | SensitiveBroadcast.java:38:31:38:36 | intent | -| SensitiveBroadcast.java:50:22:50:29 | password : String | SensitiveBroadcast.java:52:31:52:36 | intent | +| SensitiveBroadcast.java:50:9:50:16 | userinfo [post update] : ArrayList | SensitiveBroadcast.java:52:31:52:36 | intent | +| SensitiveBroadcast.java:50:22:50:29 | password : String | SensitiveBroadcast.java:50:9:50:16 | userinfo [post update] : ArrayList | | SensitiveBroadcast.java:97:35:97:40 | ticket : String | SensitiveBroadcast.java:98:54:98:59 | intent | | SensitiveBroadcast.java:109:32:109:39 | passcode : String | SensitiveBroadcast.java:111:54:111:59 | intent | | SensitiveBroadcast.java:136:33:136:38 | passwd : String | SensitiveBroadcast.java:140:54:140:59 | intent | @@ -15,6 +16,7 @@ nodes | SensitiveBroadcast.java:26:31:26:36 | intent | semmle.label | intent | | SensitiveBroadcast.java:36:35:36:39 | email : String | semmle.label | email : String | | SensitiveBroadcast.java:38:31:38:36 | intent | semmle.label | intent | +| SensitiveBroadcast.java:50:9:50:16 | userinfo [post update] : ArrayList | semmle.label | userinfo [post update] : ArrayList | | SensitiveBroadcast.java:50:22:50:29 | password : String | semmle.label | password : String | | SensitiveBroadcast.java:52:31:52:36 | intent | semmle.label | intent | | SensitiveBroadcast.java:97:35:97:40 | ticket : String | semmle.label | ticket : String | diff --git a/java/ql/test/library-tests/dataflow/collections/flow.expected b/java/ql/test/library-tests/dataflow/collections/flow.expected index d54e9921856..293e82c9759 100644 --- a/java/ql/test/library-tests/dataflow/collections/flow.expected +++ b/java/ql/test/library-tests/dataflow/collections/flow.expected @@ -85,9 +85,6 @@ | ContainterTest.java:46:4:46:38 | navMap | ContainterTest.java:199:8:199:48 | subMap(...) | | ContainterTest.java:46:4:46:38 | navMap | ContainterTest.java:200:8:200:34 | tailMap(...) | | ContainterTest.java:47:4:47:48 | syncHashMap | ContainterTest.java:203:8:203:29 | elements(...) | -| ContainterTest.java:47:4:47:48 | syncHashMap | ContainterTest.java:204:8:204:42 | search(...) | -| ContainterTest.java:47:4:47:48 | syncHashMap | ContainterTest.java:205:8:205:55 | searchEntries(...) | -| ContainterTest.java:47:4:47:48 | syncHashMap | ContainterTest.java:206:8:206:43 | searchValues(...) | | ContainterTest.java:48:4:48:34 | dict | ContainterTest.java:209:8:209:22 | elements(...) | | ContainterTest.java:48:4:48:34 | dict | ContainterTest.java:210:8:210:25 | get(...) | | ContainterTest.java:48:4:48:34 | dict | ContainterTest.java:211:8:211:31 | put(...) | diff --git a/java/ql/test/library-tests/dataflow/getter/getter.ql b/java/ql/test/library-tests/dataflow/getter/getter.ql index 02e6920fc7e..e218ccbcee5 100644 --- a/java/ql/test/library-tests/dataflow/getter/getter.ql +++ b/java/ql/test/library-tests/dataflow/getter/getter.ql @@ -5,6 +5,9 @@ import semmle.code.java.dataflow.internal.DataFlowImplSpecific::Private from Node n1, Content f, Node n2 where - read(n1, f, n2) or - getterStep(n1, f, n2) + ( + read(n1, f, n2) or + getterStep(n1, f, n2) + ) and + n1.getEnclosingCallable().fromSource() select n1, n2, f diff --git a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected index 1973eb91fe4..75b743dcaab 100644 --- a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected +++ b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected @@ -1,8 +1,8 @@ -| ArraysTest.java:7:17:7:21 | "one" | ArraysTest.java:7:3:7:22 | asList(...) | +| ArraysTest.java:6:3:6:17 | new ..[] { .. } | ArraysTest.java:6:3:6:17 | asList(...) | +| ArraysTest.java:7:3:7:22 | new ..[] { .. } | ArraysTest.java:7:3:7:22 | asList(...) | | ArraysTest.java:7:17:7:21 | "one" | ArraysTest.java:7:3:7:22 | new ..[] { .. } | -| ArraysTest.java:8:17:8:21 | "two" | ArraysTest.java:8:3:8:31 | asList(...) | +| ArraysTest.java:8:3:8:31 | new ..[] { .. } | ArraysTest.java:8:3:8:31 | asList(...) | | ArraysTest.java:8:17:8:21 | "two" | ArraysTest.java:8:3:8:31 | new ..[] { .. } | -| ArraysTest.java:8:24:8:30 | "three" | ArraysTest.java:8:3:8:31 | asList(...) | | ArraysTest.java:8:24:8:30 | "three" | ArraysTest.java:8:3:8:31 | new ..[] { .. } | | ArraysTest.java:9:17:9:22 | source | ArraysTest.java:9:3:9:27 | copyOf(...) | | ArraysTest.java:10:22:10:27 | source | ArraysTest.java:10:3:10:35 | copyOfRange(...) | @@ -18,14 +18,13 @@ | ArraysTest.java:19:55:19:55 | x | ArraysTest.java:19:38:19:56 | toString(...) | | ArraysTest.java:20:30:20:36 | Integer | ArraysTest.java:20:30:20:48 | toString(...) | | ArraysTest.java:20:47:20:47 | x | ArraysTest.java:20:30:20:48 | toString(...) | +| CollectionsTest.java:9:3:9:26 | new ..[] { .. } | CollectionsTest.java:9:22:9:25 | list [post update] | +| CollectionsTest.java:10:3:10:33 | new ..[] { .. } | CollectionsTest.java:10:22:10:25 | list [post update] | | CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:3:10:33 | new ..[] { .. } | -| CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:22:10:25 | list [post update] | +| CollectionsTest.java:11:3:11:42 | new ..[] { .. } | CollectionsTest.java:11:22:11:25 | list [post update] | | CollectionsTest.java:11:28:11:32 | "two" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } | -| CollectionsTest.java:11:28:11:32 | "two" | CollectionsTest.java:11:22:11:25 | list [post update] | | CollectionsTest.java:11:35:11:41 | "three" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } | -| CollectionsTest.java:11:35:11:41 | "three" | CollectionsTest.java:11:22:11:25 | list [post update] | | CollectionsTest.java:12:28:12:49 | new String[] | CollectionsTest.java:12:22:12:25 | list [post update] | -| CollectionsTest.java:12:28:12:49 | {...} | CollectionsTest.java:12:28:12:49 | new String[] | | CollectionsTest.java:12:42:12:47 | "four" | CollectionsTest.java:12:28:12:49 | {...} | | CollectionsTest.java:14:27:14:30 | list | CollectionsTest.java:14:3:14:45 | checkedList(...) | | CollectionsTest.java:15:19:15:22 | list | CollectionsTest.java:15:3:15:23 | min(...) | @@ -47,14 +46,14 @@ | CollectionsTest.java:33:16:33:19 | "v1" | CollectionsTest.java:33:3:33:32 | of(...) | | CollectionsTest.java:33:28:33:31 | "v2" | CollectionsTest.java:33:3:33:32 | of(...) | | CollectionsTest.java:34:14:34:16 | map | CollectionsTest.java:34:3:34:17 | copyOf(...) | +| CollectionsTest.java:35:3:35:17 | new ..[] { .. } | CollectionsTest.java:35:3:35:17 | ofEntries(...) | +| CollectionsTest.java:36:3:36:38 | new ..[] { .. } | CollectionsTest.java:36:3:36:38 | ofEntries(...) | | CollectionsTest.java:36:17:36:37 | entry(...) | CollectionsTest.java:36:3:36:38 | new ..[] { .. } | -| CollectionsTest.java:36:17:36:37 | entry(...) | CollectionsTest.java:36:3:36:38 | ofEntries(...) | | CollectionsTest.java:36:33:36:36 | "v3" | CollectionsTest.java:36:17:36:37 | entry(...) | +| CollectionsTest.java:37:3:37:61 | new ..[] { .. } | CollectionsTest.java:37:3:37:61 | ofEntries(...) | | CollectionsTest.java:37:17:37:37 | entry(...) | CollectionsTest.java:37:3:37:61 | new ..[] { .. } | -| CollectionsTest.java:37:17:37:37 | entry(...) | CollectionsTest.java:37:3:37:61 | ofEntries(...) | | CollectionsTest.java:37:33:37:36 | "v4" | CollectionsTest.java:37:17:37:37 | entry(...) | | CollectionsTest.java:37:40:37:60 | entry(...) | CollectionsTest.java:37:3:37:61 | new ..[] { .. } | -| CollectionsTest.java:37:40:37:60 | entry(...) | CollectionsTest.java:37:3:37:61 | ofEntries(...) | | CollectionsTest.java:37:56:37:59 | "v5" | CollectionsTest.java:37:40:37:60 | entry(...) | | Test.java:24:32:24:38 | string2 | Test.java:24:17:24:39 | decode(...) | | Test.java:25:46:25:51 | bytes2 | Test.java:25:31:25:52 | encode(...) | diff --git a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql index 1520ea7347d..8e2f6ef2646 100644 --- a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql +++ b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql @@ -1,12 +1,38 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.internal.TaintTrackingUtil +import semmle.code.java.dataflow.internal.DataFlowNodes::Private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +predicate taintFlowThrough(DataFlow::ParameterNode p) { + exists(ReturnNode ret | localTaint(p, ret)) +} + +predicate taintFlowUpdate(DataFlow::ParameterNode p1, DataFlow::ParameterNode p2) { + exists(DataFlow::PostUpdateNode ret | localTaint(p1, ret) | ret.getPreUpdateNode() = p2) +} + from DataFlow::Node src, DataFlow::Node sink where ( localAdditionalTaintStep(src, sink) or FlowSummaryImpl::Private::Steps::summaryThroughStep(src, sink, false) ) and - not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) + not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) and + not FlowSummaryImpl::Private::Steps::summaryReadStep(src, _, sink) and + not FlowSummaryImpl::Private::Steps::summaryStoreStep(src, _, sink) + or + exists(ArgumentNode arg, MethodAccess call, DataFlow::ParameterNode p, int i | + src = arg and + p.isParameterOf(call.getMethod().getSourceDeclaration(), i) and + arg.argumentOf(call, i) + | + sink.asExpr() = call and + taintFlowThrough(p) + or + exists(DataFlow::ParameterNode p2, int j | + sink.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).argumentOf(call, j) and + taintFlowUpdate(p, p2) and + p2.isParameterOf(_, j) + ) + ) select src, sink diff --git a/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java b/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java index a6660c87252..3e45989d1c9 100644 --- a/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java +++ b/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java @@ -33,14 +33,14 @@ class Test { byte x; byte[] tgt = new byte[100]; - x = tgt[0]; // not tainted + sink(tgt); // not tainted IOUtils.read(inp, tgt); - x = tgt[0]; // tainted + sink(tgt); // tainted tgt = new byte[100]; - x = tgt[0]; // not tainted + sink(tgt); // not tainted IOUtils.readFully(inp, tgt); - x = tgt[0]; // tainted + sink(tgt); // tainted writer = new StringWriter(); writer.toString(); // not tainted @@ -62,4 +62,6 @@ class Test { IOUtils.writeLines(new ArrayList(), s, writer); writer.toString(); // tainted } + + static void sink(Object o) { } } diff --git a/java/ql/test/library-tests/dataflow/taint-ioutils/dataFlow.expected b/java/ql/test/library-tests/dataflow/taint-ioutils/dataFlow.expected index 1a736aa24c9..1902605e618 100644 --- a/java/ql/test/library-tests/dataflow/taint-ioutils/dataFlow.expected +++ b/java/ql/test/library-tests/dataflow/taint-ioutils/dataFlow.expected @@ -28,14 +28,10 @@ | Test.java:32:3:32:19 | toString(...) | | Test.java:37:16:37:18 | inp | | Test.java:37:21:37:23 | tgt [post update] | -| Test.java:38:3:38:12 | ...=... | -| Test.java:38:7:38:9 | tgt | -| Test.java:38:7:38:12 | ...[...] | +| Test.java:38:8:38:10 | tgt | | Test.java:42:21:42:23 | inp | | Test.java:42:26:42:28 | tgt [post update] | -| Test.java:43:3:43:12 | ...=... | -| Test.java:43:7:43:9 | tgt | -| Test.java:43:7:43:12 | ...[...] | +| Test.java:43:8:43:10 | tgt | | Test.java:47:17:47:21 | chars | | Test.java:47:24:47:29 | writer [post update] | | Test.java:48:3:48:8 | writer | diff --git a/java/ql/test/library-tests/dataflow/taint/test.expected b/java/ql/test/library-tests/dataflow/taint/test.expected index 54aafdb26e7..0953353f363 100644 --- a/java/ql/test/library-tests/dataflow/taint/test.expected +++ b/java/ql/test/library-tests/dataflow/taint/test.expected @@ -3,7 +3,6 @@ | A.java:33:23:33:29 | taint(...) | A.java:34:10:34:27 | toByteArray(...) | | A.java:46:27:46:33 | taint(...) | A.java:47:10:47:30 | toByteArray(...) | | A.java:55:58:55:64 | taint(...) | A.java:61:10:61:16 | dh.data | -| A.java:72:16:72:22 | taint(...) | A.java:73:10:73:10 | b | | B.java:15:21:15:27 | taint(...) | B.java:18:10:18:16 | aaaargs | | B.java:15:21:15:27 | taint(...) | B.java:21:10:21:10 | s | | B.java:15:21:15:27 | taint(...) | B.java:24:10:24:15 | concat | diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/ObjectUtilsTest.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/ObjectUtilsTest.java index 58ee4d262e6..5b2eda3c30f 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/ObjectUtilsTest.java +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/ObjectUtilsTest.java @@ -17,22 +17,22 @@ public class ObjectUtilsTest { sink(ObjectUtils.CONST_BYTE(IntSource.taint())); // $hasValueFlow sink(ObjectUtils.defaultIfNull(taint(), null)); // $hasValueFlow sink(ObjectUtils.defaultIfNull(null, taint())); // $hasValueFlow - sink(ObjectUtils.firstNonNull(taint(), null, null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.firstNonNull(null, taint(), null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.firstNonNull(null, null, taint())); // $ MISSING:hasValueFlow + sink(ObjectUtils.firstNonNull(taint(), null, null)); // $ hasValueFlow + sink(ObjectUtils.firstNonNull(null, taint(), null)); // $ hasValueFlow + sink(ObjectUtils.firstNonNull(null, null, taint())); // $ hasValueFlow sink(ObjectUtils.getIfNull(taint(), null)); // $hasValueFlow - sink(ObjectUtils.max(taint(), null, null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.max(null, taint(), null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.max(null, null, taint())); // $ MISSING:hasValueFlow - sink(ObjectUtils.median(taint(), null, null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.median((String)null, taint(), null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.median((String)null, null, taint())); // $ MISSING:hasValueFlow - sink(ObjectUtils.min(taint(), null, null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.min(null, taint(), null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.min(null, null, taint())); // $ MISSING:hasValueFlow - sink(ObjectUtils.mode(taint(), null, null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.mode(null, taint(), null)); // $ MISSING:hasValueFlow - sink(ObjectUtils.mode(null, null, taint())); // $ MISSING:hasValueFlow + sink(ObjectUtils.max(taint(), null, null)); // $ hasValueFlow + sink(ObjectUtils.max(null, taint(), null)); // $ hasValueFlow + sink(ObjectUtils.max(null, null, taint())); // $ hasValueFlow + sink(ObjectUtils.median(taint(), null, null)); // $ hasValueFlow + sink(ObjectUtils.median((String)null, taint(), null)); // $ hasValueFlow + sink(ObjectUtils.median((String)null, null, taint())); // $ hasValueFlow + sink(ObjectUtils.min(taint(), null, null)); // $ hasValueFlow + sink(ObjectUtils.min(null, taint(), null)); // $ hasValueFlow + sink(ObjectUtils.min(null, null, taint())); // $ hasValueFlow + sink(ObjectUtils.mode(taint(), null, null)); // $ hasValueFlow + sink(ObjectUtils.mode(null, taint(), null)); // $ hasValueFlow + sink(ObjectUtils.mode(null, null, taint())); // $ hasValueFlow sink(ObjectUtils.requireNonEmpty(taint(), "message")); // $hasValueFlow sink(ObjectUtils.requireNonEmpty("not null", taint())); // GOOD (message doesn't propagate to the return) sink(ObjectUtils.toString(taint(), "default string")); // GOOD (first argument is stringified) diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/Test.java b/java/ql/test/library-tests/frameworks/apache-commons-lang3/Test.java index 28cbf5178b8..3d3e47b2bd0 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/Test.java +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/Test.java @@ -50,10 +50,10 @@ class Test { sink(StringUtils.deleteWhitespace(taint())); // $hasTaintFlow sink(StringUtils.difference(taint(), "rhs")); // $hasTaintFlow sink(StringUtils.difference("lhs", taint())); // $hasTaintFlow - sink(StringUtils.firstNonBlank(taint(), "second string")); // $hasTaintFlow - sink(StringUtils.firstNonBlank("first string", taint())); // $hasTaintFlow - sink(StringUtils.firstNonEmpty(taint(), "second string")); // $hasTaintFlow - sink(StringUtils.firstNonEmpty("first string", taint())); // $hasTaintFlow + sink(StringUtils.firstNonBlank(taint(), "second string")); // $hasValueFlow + sink(StringUtils.firstNonBlank("first string", taint())); // $hasValueFlow + sink(StringUtils.firstNonEmpty(taint(), "second string")); // $hasValueFlow + sink(StringUtils.firstNonEmpty("first string", taint())); // $hasValueFlow sink(StringUtils.getBytes(taint(), (Charset)null)); // $hasTaintFlow sink(StringUtils.getBytes(taint(), "some charset")); // $hasTaintFlow // GOOD: charset names are not a source of taint @@ -216,12 +216,12 @@ class Test { sink(StringUtils.strip(taint())); // $hasTaintFlow sink(StringUtils.strip(taint(), "charstoremove")); // $hasTaintFlow sink(StringUtils.stripAccents(taint())); // $hasTaintFlow - sink(StringUtils.stripAll(new String[] { taint() }, "charstoremove")); // $hasTaintFlow + sink(StringUtils.stripAll(new String[] { taint() }, "charstoremove")[0]); // $hasTaintFlow sink(StringUtils.stripEnd(taint(), "charstoremove")); // $hasTaintFlow sink(StringUtils.stripStart(taint(), "charstoremove")); // $hasTaintFlow // GOOD (next 4 calls): stripped chars do not flow to the return value. sink(StringUtils.strip("original text", taint())); - sink(StringUtils.stripAll(new String[] { "original text" }, taint())); + sink(StringUtils.stripAll(new String[] { "original text" }, taint())[0]); sink(StringUtils.stripEnd("original text", taint())); sink(StringUtils.stripStart("original text", taint())); sink(StringUtils.stripToEmpty(taint())); // $hasTaintFlow @@ -275,4 +275,4 @@ class Test { } -} \ No newline at end of file +} diff --git a/java/ql/test/library-tests/frameworks/guava/TestBase.java b/java/ql/test/library-tests/frameworks/guava/TestBase.java index ad75f5cafbf..8da63965d58 100644 --- a/java/ql/test/library-tests/frameworks/guava/TestBase.java +++ b/java/ql/test/library-tests/frameworks/guava/TestBase.java @@ -18,7 +18,7 @@ class TestBase { sink(Strings.lenientFormat(x, 3)); // $numTaintFlow=1 sink(Strings.commonPrefix(x, "abc")); sink(Strings.commonSuffix(x, "cde")); - sink(Strings.lenientFormat("%s = %s", x, 3)); // $ MISSING:numTaintFlow=1 + sink(Strings.lenientFormat("%s = %s", x, 3)); // $ numTaintFlow=1 } void test2() { diff --git a/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected b/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected index 4a29161c63c..ea822181844 100644 --- a/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected +++ b/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected @@ -1,8 +1,10 @@ edges | Test.java:6:35:6:44 | arg : String | Test.java:7:44:7:69 | ... + ... | | Test.java:6:35:6:44 | arg : String | Test.java:10:29:10:74 | new String[] | -| Test.java:6:35:6:44 | arg : String | Test.java:18:29:18:31 | cmd | +| Test.java:6:35:6:44 | arg : String | Test.java:16:13:16:25 | ... + ... : String | | Test.java:6:35:6:44 | arg : String | Test.java:24:29:24:32 | cmd1 | +| Test.java:16:5:16:7 | cmd [post update] : List | Test.java:18:29:18:31 | cmd | +| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : List | | Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... | | Test.java:57:27:57:39 | args : String[] | Test.java:60:20:60:22 | arg : String | | Test.java:57:27:57:39 | args : String[] | Test.java:61:23:61:25 | arg : String | @@ -12,6 +14,8 @@ nodes | Test.java:6:35:6:44 | arg : String | semmle.label | arg : String | | Test.java:7:44:7:69 | ... + ... | semmle.label | ... + ... | | Test.java:10:29:10:74 | new String[] | semmle.label | new String[] | +| Test.java:16:5:16:7 | cmd [post update] : List | semmle.label | cmd [post update] : List | +| Test.java:16:13:16:25 | ... + ... : String | semmle.label | ... + ... : String | | Test.java:18:29:18:31 | cmd | semmle.label | cmd | | Test.java:24:29:24:32 | cmd1 | semmle.label | cmd1 | | Test.java:28:38:28:47 | arg : String | semmle.label | arg : String | From 901996f9fdf7eb94c65b8f9e95253f11843539fd Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 12 May 2021 18:04:20 +0200 Subject: [PATCH 074/272] Java: Add collection flow test. --- .../library-tests/dataflow/collections/B.java | 1821 +++++++++++++++++ .../dataflow/collections/ContainterTest.java | 2 +- .../collections/containerflow.expected | 0 .../dataflow/collections/containerflow.ql | 45 + 4 files changed, 1867 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/library-tests/dataflow/collections/B.java create mode 100644 java/ql/test/library-tests/dataflow/collections/containerflow.expected create mode 100644 java/ql/test/library-tests/dataflow/collections/containerflow.ql diff --git a/java/ql/test/library-tests/dataflow/collections/B.java b/java/ql/test/library-tests/dataflow/collections/B.java new file mode 100644 index 00000000000..1c0384a71c6 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/collections/B.java @@ -0,0 +1,1821 @@ +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.*; + +public class B { + static Object source() { return null; } + + static void sink(Object obj) { } + + static Object[] storeArrayElement(Object obj) { return null; } + static Object storeElement(Object obj) { return null; } + static Object storeMapKey(Object obj) { return null; } + static Object storeMapValue(Object obj) { return null; } + + static Object readArrayElement(Object obj) { return null; } + static Object readElement(Object obj) { return null; } + static Object readMapKey(Object obj) { return null; } + static Object readMapValue(Object obj) { return null; } + + void foo() throws InterruptedException { + { + // "java.util;Map<>$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Map.Entry)in).getValue(); sink(out); // $ hasValueFlow + } + { + // "java.util;Map<>$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Map.Entry)in).setValue(null); sink(out); // $ hasValueFlow + } + { + // "java.util;Map<>$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value", + Map.Entry out = null; + Object in = source(); out.setValue(in); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.lang;Iterable;true;iterator;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Iterable)in).iterator(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.lang;Iterable;true;spliterator;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Iterable)in).spliterator(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Iterator;true;next;;;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Iterator)in).next(); sink(out); // $ hasValueFlow + } + { + // "java.util;ListIterator;true;previous;;;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((ListIterator)in).previous(); sink(out); // $ hasValueFlow + } + { + // "java.util;ListIterator;true;add;(Object);;Argument[0];Element of Argument[-1];value", + ListIterator out = null; + Object in = source(); out.add(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;ListIterator;true;set;(Object);;Argument[0];Element of Argument[-1];value", + ListIterator out = null; + Object in = source(); out.set(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Enumeration;true;asIterator;;;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Enumeration)in).asIterator(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Enumeration;true;nextElement;;;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Enumeration)in).nextElement(); sink(out); // $ hasValueFlow + } + { + // "java.util;Map;true;computeIfAbsent;;;MapValue of Argument[-1];ReturnValue;value", + 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", + Object out = ((Map)null).computeIfAbsent(null,k -> source()); sink(out); + } + { + // "java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];MapValue of Argument[-1];value", + Object out = null; + ((Map)out).computeIfAbsent(null,k -> source()); sink(readMapValue(out)); + } + { + // "java.util;Map;true;entrySet;;;MapValue of Argument[-1];MapValue of Element of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Map)in).entrySet(); sink(readMapValue(readElement(out))); // $ hasValueFlow + } + { + // "java.util;Map;true;entrySet;;;MapKey of Argument[-1];MapKey of Element of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((Map)in).entrySet(); sink(readMapKey(readElement(out))); // $ hasValueFlow + } + { + // "java.util;Map;true;get;;;MapValue of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Map)in).get(null); sink(out); // $ hasValueFlow + } + { + // "java.util;Map;true;getOrDefault;;;MapValue of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Map)in).getOrDefault(null,null); sink(out); // $ hasValueFlow + } + { + // "java.util;Map;true;getOrDefault;;;Argument[1];ReturnValue;value", + Object out = null; + Object in = source(); out = ((Map)null).getOrDefault(null,in); sink(out); // $ hasValueFlow + } + { + // "java.util;Map;true;put;;;MapValue of Argument[-1];ReturnValue;value", + 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[-1];value", + Map out = null; + Object in = source(); out.put(in,null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;Map;true;put;;;Argument[1];MapValue of Argument[-1];value", + Map out = null; + Object in = source(); out.put(null,in); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;Map;true;putIfAbsent;;;MapValue of Argument[-1];ReturnValue;value", + 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[-1];value", + Map out = null; + Object in = source(); out.putIfAbsent(in,null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;Map;true;putIfAbsent;;;Argument[1];MapValue of Argument[-1];value", + Map out = null; + Object in = source(); out.putIfAbsent(null,in); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;Map;true;remove;(Object);;MapValue of Argument[-1];ReturnValue;value", + 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[-1];ReturnValue;value", + 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[-1];value", + 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[-1];value", + 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[-1];value", + 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[-1];value", + Map out = null; + Object in = source(); out.replace(null,null,in); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;Map;true;keySet;();;MapKey of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((Map)in).keySet(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Map;true;values;();;MapValue of Argument[-1];Element of ReturnValue;value", + Object 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[-1];value", + 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[-1];value", + 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[-1];value", + Map out = null; + Object in = storeMapValue(source()); out.putAll((Map)in); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;Collection;true;parallelStream;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collection)in).parallelStream(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collection;true;stream;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collection)in).stream(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collection)in).toArray(); sink(readArrayElement(out)); // $ hasValueFlow + } + { + // "java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of Argument[0];value", + Object[] out = null; + Object in = storeElement(source()); ((Collection)in).toArray(out); sink(readArrayElement(out)); // $ hasValueFlow + } + { + // "java.util;Collection;true;add;;;Argument[0];Element of Argument[-1];value", + 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[-1];value", + Collection out = null; + Object in = storeElement(source()); out.addAll((Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;List;true;get;(int);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((List)in).get(0); sink(out); // $ hasValueFlow + } + { + // "java.util;List;true;listIterator;;;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((List)in).listIterator(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;List;true;remove;(int);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((List)in).remove(0); sink(out); // $ hasValueFlow + } + { + // "java.util;List;true;set;(int,Object);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((List)in).set(0,null); sink(out); // $ hasValueFlow + } + { + // "java.util;List;true;set;(int,Object);;Argument[1];Element of Argument[-1];value", + List out = null; + Object in = source(); out.set(0,in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;List;true;subList;;;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((List)in).subList(0,0); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;List;true;add;(int,Object);;Argument[1];Element of Argument[-1];value", + 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[-1];value", + List out = null; + Object in = storeElement(source()); out.addAll(0,(Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Vector;true;elementAt;(int);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Vector)in).elementAt(0); sink(out); // $ hasValueFlow + } + { + // "java.util;Vector;true;elements;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Vector)in).elements(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Vector;true;firstElement;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Vector)in).firstElement(); sink(out); // $ hasValueFlow + } + { + // "java.util;Vector;true;lastElement;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Vector)in).lastElement(); sink(out); // $ hasValueFlow + } + { + // "java.util;Vector;true;addElement;(Object);;Argument[0];Element of Argument[-1];value", + 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[-1];value", + 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[-1];value", + Vector out = null; + Object in = source(); out.setElementAt(in,0); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Vector;true;copyInto;(Object[]);;Element of Argument[-1];ArrayElement of Argument[0];value", + Object[] out = null; + Object in = storeElement(source()); ((Vector)in).copyInto(out); sink(readArrayElement(out)); // $ hasValueFlow + } + { + // "java.util;Stack;true;peek;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Stack)in).peek(); sink(out); // $ hasValueFlow + } + { + // "java.util;Stack;true;pop;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Stack)in).pop(); sink(out); // $ hasValueFlow + } + { + // "java.util;Stack;true;push;(Object);;Argument[0];Element of Argument[-1];value", + Stack out = null; + Object in = source(); out.push(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Queue;true;element;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Queue)in).element(); sink(out); // $ hasValueFlow + } + { + // "java.util;Queue;true;peek;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Queue)in).peek(); sink(out); // $ hasValueFlow + } + { + // "java.util;Queue;true;poll;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Queue)in).poll(); sink(out); // $ hasValueFlow + } + { + // "java.util;Queue;true;remove;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Queue)in).remove(); sink(out); // $ hasValueFlow + } + { + // "java.util;Queue;true;offer;(Object);;Argument[0];Element of Argument[-1];value", + Queue out = null; + Object in = source(); out.offer(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Deque;true;descendingIterator;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).descendingIterator(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Deque;true;getFirst;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).getFirst(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;getLast;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).getLast(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;peekFirst;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).peekFirst(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;peekLast;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).peekLast(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;pollFirst;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).pollFirst(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;pollLast;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).pollLast(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;pop;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).pop(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;removeFirst;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).removeFirst(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;removeLast;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Deque)in).removeLast(); sink(out); // $ hasValueFlow + } + { + // "java.util;Deque;true;push;(Object);;Argument[0];Element of Argument[-1];value", + Deque out = null; + Object in = source(); out.push(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Deque;true;offerLast;(Object);;Argument[0];Element of Argument[-1];value", + Deque out = null; + Object in = source(); out.offerLast(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Deque;true;offerFirst;(Object);;Argument[0];Element of Argument[-1];value", + Deque out = null; + Object in = source(); out.offerFirst(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Deque;true;addLast;(Object);;Argument[0];Element of Argument[-1];value", + Deque out = null; + Object in = source(); out.addLast(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Deque;true;addFirst;(Object);;Argument[0];Element of Argument[-1];value", + Deque out = null; + Object in = source(); out.addFirst(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((BlockingDeque)in).pollFirst(0,null); sink(out); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((BlockingDeque)in).pollLast(0,null); sink(out); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingDeque;true;takeFirst;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((BlockingDeque)in).takeFirst(); sink(out); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingDeque;true;takeLast;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((BlockingDeque)in).takeLast(); sink(out); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((BlockingQueue)in).poll(0,null); sink(out); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingQueue;true;take;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((BlockingQueue)in).take(); sink(out); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value", + 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[-1];value", + 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[-1];value", + 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[-1];value", + 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[-1];value", + 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[-1];value", + BlockingDeque out = null; + Object in = source(); out.putFirst(in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Element of Argument[-1];Element of Argument[0];value", + Collection out = null; + Object in = storeElement(source()); ((BlockingQueue)in).drainTo(out,0); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Element of Argument[-1];Element of Argument[0];value", + Collection out = null; + Object in = storeElement(source()); ((BlockingQueue)in).drainTo(out); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util.concurrent;ConcurrentHashMap;true;elements;();;MapValue of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((ConcurrentHashMap)in).elements(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Dictionary;true;elements;();;MapValue of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Dictionary)in).elements(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Dictionary;true;get;(Object);;MapValue of Argument[-1];ReturnValue;value", + 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[-1];ReturnValue;value", + 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[-1];value", + 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[-1];value", + Dictionary out = null; + Object in = source(); out.put(null,in); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;Dictionary;true;remove;(Object);;MapValue of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((Dictionary)in).remove(null); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;ceilingEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).ceilingEntry(null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;ceilingEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).ceilingEntry(null); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;descendingMap;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).descendingMap(); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;descendingMap;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).descendingMap(); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;firstEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).firstEntry(); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;firstEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).firstEntry(); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;floorEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).floorEntry(null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;floorEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object 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[-1];MapKey of ReturnValue;value", + Object 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[-1];MapValue of ReturnValue;value", + Object 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[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).higherEntry(null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;higherEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).higherEntry(null); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;lastEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).lastEntry(); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;lastEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).lastEntry(); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;lowerEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).lowerEntry(null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;lowerEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).lowerEntry(null); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;pollFirstEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).pollFirstEntry(); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;pollFirstEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((NavigableMap)in).pollFirstEntry(); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;pollLastEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((NavigableMap)in).pollLastEntry(); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;NavigableMap;true;pollLastEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object 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[-1];MapKey of ReturnValue;value", + Object 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[-1];MapValue of ReturnValue;value", + Object 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[-1];MapKey of ReturnValue;value", + Object 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[-1];MapValue of ReturnValue;value", + Object 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[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).ceiling(null); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;descendingIterator;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).descendingIterator(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;descendingSet;();;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).descendingSet(); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;floor;(Object);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).floor(null); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;headSet;(Object,boolean);;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).headSet(null,true); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;higher;(Object);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).higher(null); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;lower;(Object);;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).lower(null); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;pollFirst;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).pollFirst(); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;pollLast;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).pollLast(); sink(out); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).subSet(null,true,null,true); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;NavigableSet;true;tailSet;(Object,boolean);;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((NavigableSet)in).tailSet(null,true); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;SortedMap;true;headMap;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((SortedMap)in).headMap(null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;SortedMap;true;headMap;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object 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[-1];MapKey of ReturnValue;value", + Object 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[-1];MapValue of ReturnValue;value", + Object 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[-1];MapKey of ReturnValue;value", + Object out = null; + Object in = storeMapKey(source()); out = ((SortedMap)in).tailMap(null); sink(readMapKey(out)); // $ hasValueFlow + } + { + // "java.util;SortedMap;true;tailMap;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value", + Object out = null; + Object in = storeMapValue(source()); out = ((SortedMap)in).tailMap(null); sink(readMapValue(out)); // $ hasValueFlow + } + { + // "java.util;SortedSet;true;first;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((SortedSet)in).first(); sink(out); // $ hasValueFlow + } + { + // "java.util;SortedSet;true;headSet;(Object);;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((SortedSet)in).headSet(null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;SortedSet;true;last;();;Element of Argument[-1];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((SortedSet)in).last(); sink(out); // $ hasValueFlow + } + { + // "java.util;SortedSet;true;subSet;(Object,Object);;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((SortedSet)in).subSet(null,null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;SortedSet;true;tailSet;(Object);;Element of Argument[-1];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((SortedSet)in).tailSet(null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value", + 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[-1];value", + 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[-1];value", + 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", + Object out = null; + Object in = storeElement(source()); out = List.copyOf((Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;List;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object out = null; + Object in = storeElement(source()); out = Set.copyOf((Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Set;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + 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", + 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", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).list((Enumeration)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;enumeration;(Collection);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).enumeration((Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;nCopies;(int,Object);;Argument[1];Element of ReturnValue;value", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).checkedList((List)in,null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).checkedNavigableSet((NavigableSet)in,null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).checkedSortedSet((SortedSet)in,null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;checkedSet;(Set,Class);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).checkedSet((Set)in,null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;checkedCollection;(Collection,Class);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).checkedCollection((Collection)in,null); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).synchronizedList((List)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).synchronizedNavigableSet((NavigableSet)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).synchronizedSortedSet((SortedSet)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;synchronizedSet;(Set);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).synchronizedSet((Set)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;synchronizedCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).synchronizedCollection((Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object 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", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).unmodifiableList((List)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).unmodifiableNavigableSet((NavigableSet)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).unmodifiableSortedSet((SortedSet)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;unmodifiableSet;(Set);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).unmodifiableSet((Set)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;unmodifiableCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).unmodifiableCollection((Collection)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;max;;;Element of Argument[0];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).max((Collection)in); sink(out); // $ hasValueFlow + } + { + // "java.util;Collections;false;min;;;Element of Argument[0];ReturnValue;value", + Object out = null; + Object in = storeElement(source()); out = ((Collections)null).min((Collection)in); sink(out); // $ hasValueFlow + } + { + // "java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];ArrayElement of Argument[0];value", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + 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", + List out = null; + Object in = storeElement(source()); ((Collections)null).copy(out,(List)in); sink(readElement(out)); // $ hasValueFlow + } + { + // "java.util;Collections;false;fill;(List,Object);;Argument[1];Element of Argument[0];value", + 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", + Object 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" + Collection out = null; + Object[] in = storeArrayElement(source()); ((Collections)null).addAll(out,in); sink(readElement(out)); // $ hasValueFlow + } + } +} diff --git a/java/ql/test/library-tests/dataflow/collections/ContainterTest.java b/java/ql/test/library-tests/dataflow/collections/ContainterTest.java index ab9b699be9b..9c291a7b2a3 100644 --- a/java/ql/test/library-tests/dataflow/collections/ContainterTest.java +++ b/java/ql/test/library-tests/dataflow/collections/ContainterTest.java @@ -89,7 +89,7 @@ class ContainerTest { sink(stack.peek()); sink(stack.pop()); sink(stack.push("value")); // not tainted - sink(new Stack().push(source("value"))); + sink(new Stack().push(source("value"))); // $ hasValueFlow mkSink(Stack.class).push(source("value")); // java.util.Queue diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.expected b/java/ql/test/library-tests/dataflow/collections/containerflow.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ql b/java/ql/test/library-tests/dataflow/collections/containerflow.ql new file mode 100644 index 00000000000..409ff5c0107 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ql @@ -0,0 +1,45 @@ +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.ExternalFlow +import TestUtilities.InlineExpectationsTest +import DataFlow + +class SummaryModelTest extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", + ";B;false;storeArrayElement;(Object);;Argument[0];ArrayElement of ReturnValue;value", + ";B;false;storeElement;(Object);;Argument[0];Element of ReturnValue;value", + ";B;false;storeMapKey;(Object);;Argument[0];MapKey of ReturnValue;value", + ";B;false;storeMapValue;(Object);;Argument[0];MapValue of ReturnValue;value", + ";B;false;readArrayElement;(Object);;ArrayElement of Argument[0];ReturnValue;value", + ";B;false;readElement;(Object);;Element of Argument[0];ReturnValue;value", + ";B;false;readMapKey;(Object);;MapKey of Argument[0];ReturnValue;value", + ";B;false;readMapValue;(Object);;MapValue of Argument[0];ReturnValue;value" + ] + } +} + +class ContainerFlowConf extends Configuration { + ContainerFlowConf() { this = "qltest:ContainerFlowConf" } + + override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("source") } + + override predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") } +} + +class HasFlowTest extends InlineExpectationsTest { + HasFlowTest() { this = "HasFlowTest" } + + override string getARelevantTag() { result = "hasValueFlow" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(Node src, Node sink, ContainerFlowConf conf | conf.hasFlow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} From dbe352f3ff11bbe9b7c55a9556d42dc9bc7a7822 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 20 May 2021 12:55:31 +0200 Subject: [PATCH 075/272] Java: Remove deprecated tests. --- .../local-additional-taint/ArraysTest.java | 18 +++---- .../CollectionsTest.java | 40 --------------- .../localAdditionalTaintStep.expected | 49 ------------------- 3 files changed, 9 insertions(+), 98 deletions(-) delete mode 100644 java/ql/test/library-tests/dataflow/local-additional-taint/CollectionsTest.java diff --git a/java/ql/test/library-tests/dataflow/local-additional-taint/ArraysTest.java b/java/ql/test/library-tests/dataflow/local-additional-taint/ArraysTest.java index f016cb63fd3..45190248a45 100644 --- a/java/ql/test/library-tests/dataflow/local-additional-taint/ArraysTest.java +++ b/java/ql/test/library-tests/dataflow/local-additional-taint/ArraysTest.java @@ -3,17 +3,17 @@ import java.util.List; class ArraysTest { public static void taintSteps(String[] source) { - Arrays.asList(); - Arrays.asList("one"); - Arrays.asList("two", "three"); - Arrays.copyOf(source, 10); - Arrays.copyOfRange(source, 0, 10); + + + + + Arrays.deepToString(source); - Arrays.spliterator(source); - Arrays.stream(source); + + Arrays.toString(source); - Arrays.fill(source, "value"); - Arrays.fill(source, 0, 10, "data"); + + Arrays.parallelPrefix(source, (x, y) -> x + y); Arrays.parallelPrefix(source, 0, 10, (x, y) -> x + y); Arrays.parallelSetAll(source, x -> Integer.toString(x)); diff --git a/java/ql/test/library-tests/dataflow/local-additional-taint/CollectionsTest.java b/java/ql/test/library-tests/dataflow/local-additional-taint/CollectionsTest.java deleted file mode 100644 index 7132e0051f0..00000000000 --- a/java/ql/test/library-tests/dataflow/local-additional-taint/CollectionsTest.java +++ /dev/null @@ -1,40 +0,0 @@ -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Set; -import java.util.Map; - -class CollectionsTest { - public static void taintSteps(List list, List other, Enumeration enumeration, Map map) { - Collections.addAll(list); - Collections.addAll(list, "one"); - Collections.addAll(list, "two", "three"); - Collections.addAll(list, new String[]{ "four" }); - - Collections.checkedList(list, String.class); - Collections.min(list); - Collections.enumeration(list); - Collections.list(enumeration); - Collections.singletonMap("key", "value"); - Collections.copy(list, other); - Collections.nCopies(10, "item"); - Collections.replaceAll(list, "search", "replace"); - - List.of(); - java.util.List.of("a"); - List.of("b", "c"); - java.util.List.copyOf(list); - Set.of(); - Set.of("d"); - Set.of("e" , "f"); - Set.copyOf(list); - Map.of(); - Map.of("k", "v"); - Map.of("k1", "v1", "k2", "v2"); - Map.copyOf(map); - Map.ofEntries(); - Map.ofEntries(Map.entry("k3", "v3")); - Map.ofEntries(Map.entry("k4", "v4"), Map.entry("k5", "v5")); - } -} - diff --git a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected index 75b743dcaab..b55cd7f9a5c 100644 --- a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected +++ b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected @@ -1,15 +1,3 @@ -| ArraysTest.java:6:3:6:17 | new ..[] { .. } | ArraysTest.java:6:3:6:17 | asList(...) | -| ArraysTest.java:7:3:7:22 | new ..[] { .. } | ArraysTest.java:7:3:7:22 | asList(...) | -| ArraysTest.java:7:17:7:21 | "one" | ArraysTest.java:7:3:7:22 | new ..[] { .. } | -| ArraysTest.java:8:3:8:31 | new ..[] { .. } | ArraysTest.java:8:3:8:31 | asList(...) | -| ArraysTest.java:8:17:8:21 | "two" | ArraysTest.java:8:3:8:31 | new ..[] { .. } | -| ArraysTest.java:8:24:8:30 | "three" | ArraysTest.java:8:3:8:31 | new ..[] { .. } | -| ArraysTest.java:9:17:9:22 | source | ArraysTest.java:9:3:9:27 | copyOf(...) | -| ArraysTest.java:10:22:10:27 | source | ArraysTest.java:10:3:10:35 | copyOfRange(...) | -| ArraysTest.java:12:22:12:27 | source | ArraysTest.java:12:3:12:28 | spliterator(...) | -| ArraysTest.java:13:17:13:22 | source | ArraysTest.java:13:3:13:23 | stream(...) | -| ArraysTest.java:15:23:15:29 | "value" | ArraysTest.java:15:15:15:20 | source [post update] | -| ArraysTest.java:16:30:16:35 | "data" | ArraysTest.java:16:15:16:20 | source [post update] | | ArraysTest.java:17:43:17:43 | x | ArraysTest.java:17:43:17:47 | ... + ... | | ArraysTest.java:17:47:17:47 | y | ArraysTest.java:17:43:17:47 | ... + ... | | ArraysTest.java:18:50:18:50 | x | ArraysTest.java:18:50:18:54 | ... + ... | @@ -18,43 +6,6 @@ | ArraysTest.java:19:55:19:55 | x | ArraysTest.java:19:38:19:56 | toString(...) | | ArraysTest.java:20:30:20:36 | Integer | ArraysTest.java:20:30:20:48 | toString(...) | | ArraysTest.java:20:47:20:47 | x | ArraysTest.java:20:30:20:48 | toString(...) | -| CollectionsTest.java:9:3:9:26 | new ..[] { .. } | CollectionsTest.java:9:22:9:25 | list [post update] | -| CollectionsTest.java:10:3:10:33 | new ..[] { .. } | CollectionsTest.java:10:22:10:25 | list [post update] | -| CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:3:10:33 | new ..[] { .. } | -| CollectionsTest.java:11:3:11:42 | new ..[] { .. } | CollectionsTest.java:11:22:11:25 | list [post update] | -| CollectionsTest.java:11:28:11:32 | "two" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } | -| CollectionsTest.java:11:35:11:41 | "three" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } | -| CollectionsTest.java:12:28:12:49 | new String[] | CollectionsTest.java:12:22:12:25 | list [post update] | -| CollectionsTest.java:12:42:12:47 | "four" | CollectionsTest.java:12:28:12:49 | {...} | -| CollectionsTest.java:14:27:14:30 | list | CollectionsTest.java:14:3:14:45 | checkedList(...) | -| CollectionsTest.java:15:19:15:22 | list | CollectionsTest.java:15:3:15:23 | min(...) | -| CollectionsTest.java:16:27:16:30 | list | CollectionsTest.java:16:3:16:31 | enumeration(...) | -| CollectionsTest.java:17:20:17:30 | enumeration | CollectionsTest.java:17:3:17:31 | list(...) | -| CollectionsTest.java:18:35:18:41 | "value" | CollectionsTest.java:18:3:18:42 | singletonMap(...) | -| CollectionsTest.java:19:26:19:30 | other | CollectionsTest.java:19:20:19:23 | list [post update] | -| CollectionsTest.java:20:27:20:32 | "item" | CollectionsTest.java:20:3:20:33 | nCopies(...) | -| CollectionsTest.java:21:42:21:50 | "replace" | CollectionsTest.java:21:26:21:29 | list [post update] | -| CollectionsTest.java:24:21:24:23 | "a" | CollectionsTest.java:24:3:24:24 | of(...) | -| CollectionsTest.java:25:11:25:13 | "b" | CollectionsTest.java:25:3:25:19 | of(...) | -| CollectionsTest.java:25:16:25:18 | "c" | CollectionsTest.java:25:3:25:19 | of(...) | -| CollectionsTest.java:26:25:26:28 | list | CollectionsTest.java:26:3:26:29 | copyOf(...) | -| CollectionsTest.java:28:10:28:12 | "d" | CollectionsTest.java:28:3:28:13 | of(...) | -| CollectionsTest.java:29:10:29:12 | "e" | CollectionsTest.java:29:3:29:19 | of(...) | -| CollectionsTest.java:29:16:29:18 | "f" | CollectionsTest.java:29:3:29:19 | of(...) | -| CollectionsTest.java:30:14:30:17 | list | CollectionsTest.java:30:3:30:18 | copyOf(...) | -| CollectionsTest.java:32:15:32:17 | "v" | CollectionsTest.java:32:3:32:18 | of(...) | -| CollectionsTest.java:33:16:33:19 | "v1" | CollectionsTest.java:33:3:33:32 | of(...) | -| CollectionsTest.java:33:28:33:31 | "v2" | CollectionsTest.java:33:3:33:32 | of(...) | -| CollectionsTest.java:34:14:34:16 | map | CollectionsTest.java:34:3:34:17 | copyOf(...) | -| CollectionsTest.java:35:3:35:17 | new ..[] { .. } | CollectionsTest.java:35:3:35:17 | ofEntries(...) | -| CollectionsTest.java:36:3:36:38 | new ..[] { .. } | CollectionsTest.java:36:3:36:38 | ofEntries(...) | -| CollectionsTest.java:36:17:36:37 | entry(...) | CollectionsTest.java:36:3:36:38 | new ..[] { .. } | -| CollectionsTest.java:36:33:36:36 | "v3" | CollectionsTest.java:36:17:36:37 | entry(...) | -| CollectionsTest.java:37:3:37:61 | new ..[] { .. } | CollectionsTest.java:37:3:37:61 | ofEntries(...) | -| CollectionsTest.java:37:17:37:37 | entry(...) | CollectionsTest.java:37:3:37:61 | new ..[] { .. } | -| CollectionsTest.java:37:33:37:36 | "v4" | CollectionsTest.java:37:17:37:37 | entry(...) | -| CollectionsTest.java:37:40:37:60 | entry(...) | CollectionsTest.java:37:3:37:61 | new ..[] { .. } | -| CollectionsTest.java:37:56:37:59 | "v5" | CollectionsTest.java:37:40:37:60 | entry(...) | | Test.java:24:32:24:38 | string2 | Test.java:24:17:24:39 | decode(...) | | Test.java:25:46:25:51 | bytes2 | Test.java:25:31:25:52 | encode(...) | | Test.java:27:34:27:40 | string2 | Test.java:27:13:27:41 | decode(...) | From fc913e744e57fb16a54de16668278fa61dbe5f52 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 20 May 2021 15:29:08 +0200 Subject: [PATCH 076/272] Java: Minor model fix. --- .../code/java/frameworks/jackson/JacksonSerializability.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/src/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index 6cda84512a0..618fc1d2710 100644 --- a/java/ql/src/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/src/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -280,6 +280,7 @@ private class JacksonModel extends SummaryModelCsv { row = [ "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0];ReturnValue;taint", + "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;MapValue of Argument[0];ReturnValue;taint", "com.fasterxml.jackson.databind;ObjectMapper;true;convertValue;;;Argument[0];ReturnValue;taint" ] } From 14f9a5c280b65e1e32868176cfe32a6cd2fe2490 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Jun 2021 13:08:42 +0200 Subject: [PATCH 077/272] Java: Move some CSV flow summary code into shared library --- .../code/java/dataflow/ExternalFlow.qll | 147 +++------------- .../dataflow/internal/FlowSummaryImpl.qll | 162 ++++++++++-------- .../internal/FlowSummaryImplSpecific.qll | 26 +++ 3 files changed, 143 insertions(+), 192 deletions(-) diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 33a146d07fe..57ab641483f 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -67,6 +67,7 @@ import java private import semmle.code.java.dataflow.DataFlow::DataFlow private import internal.DataFlowPrivate +private import internal.FlowSummaryImpl::Private::External private import FlowSummary /** @@ -498,10 +499,15 @@ module CsvValidation { or summaryModel(_, _, _, _, _, _, input, _, _) and pred = "summary" | - specSplit(input, part, _) and - not part.regexpMatch("|ReturnValue|ArrayElement|Element|MapKey|MapValue") and - not (part = "Argument" and pred = "sink") and - not parseArg(part, _) and + ( + invalidSpecComponent(input, part) and + not part = "" and + not (part = "Argument" and pred = "sink") and + not parseArg(part, _) + or + specSplit(input, part, _) and + parseParam(part, _) + ) and msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model." ) or @@ -510,11 +516,9 @@ module CsvValidation { or summaryModel(_, _, _, _, _, _, _, output, _) and pred = "summary" | - specSplit(output, part, _) and - not part.regexpMatch("|ReturnValue|ArrayElement|Element|MapKey|MapValue") and + invalidSpecComponent(output, part) and + not part = "" and not (part = ["Argument", "Parameter"] and pred = "source") and - not parseArg(part, _) and - not parseParam(part, _) and msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model." ) or @@ -624,7 +628,11 @@ private predicate sinkElement(Element e, string input, string kind) { ) } -private predicate summaryElement(Element e, string input, string output, string kind) { +/** + * Holds if an external flow summary exists for `e` with input specification + * `input`, output specification `output`, and kind `kind`. + */ +predicate summaryElement(Element e, string input, string output, string kind) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | @@ -633,52 +641,14 @@ private predicate summaryElement(Element e, string input, string output, string ) } -private string inOutSpec() { +/** Gets a specification used in a source model, sink model, or summary model. */ +string inOutSpec() { sourceModel(_, _, _, _, _, _, result, _) or sinkModel(_, _, _, _, _, _, result, _) or summaryModel(_, _, _, _, _, _, result, _, _) or summaryModel(_, _, _, _, _, _, _, result, _) } -private predicate specSplit(string s, string c, int n) { - inOutSpec() = s and s.splitAt(" of ", n) = c -} - -private predicate len(string s, int len) { len = 1 + max(int n | specSplit(s, _, n)) } - -private string getLast(string s) { - exists(int len | - len(s, len) and - specSplit(s, result, len - 1) - ) -} - -private predicate parseParam(string c, int n) { - specSplit(_, c, _) and - ( - c.regexpCapture("Parameter\\[([-0-9]+)\\]", 1).toInt() = n - or - exists(int n1, int n2 | - c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and - c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and - n = [n1 .. n2] - ) - ) -} - -private predicate parseArg(string c, int n) { - specSplit(_, c, _) and - ( - c.regexpCapture("Argument\\[([-0-9]+)\\]", 1).toInt() = n - or - exists(int n1, int n2 | - c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and - c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and - n = [n1 .. n2] - ) - ) -} - private predicate inputNeedsReference(string c) { c = "Argument" or parseArg(c, _) @@ -693,7 +663,7 @@ private predicate outputNeedsReference(string c) { private predicate sourceElementRef(Top ref, string output, string kind) { exists(Element e | sourceElement(e, output, kind) and - if outputNeedsReference(getLast(output)) + if outputNeedsReference(specLast(output)) then ref.(Call).getCallee().getSourceDeclaration() = e else ref = e ) @@ -702,7 +672,7 @@ private predicate sourceElementRef(Top ref, string output, string kind) { private predicate sinkElementRef(Top ref, string input, string kind) { exists(Element e | sinkElement(e, input, kind) and - if inputNeedsReference(getLast(input)) + if inputNeedsReference(specLast(input)) then ref.(Call).getCallee().getSourceDeclaration() = e else ref = e ) @@ -711,81 +681,12 @@ private predicate sinkElementRef(Top ref, string input, string kind) { private predicate summaryElementRef(Top ref, string input, string output, string kind) { exists(Element e | summaryElement(e, input, output, kind) and - if inputNeedsReference(getLast(input)) + if inputNeedsReference(specLast(input)) then ref.(Call).getCallee().getSourceDeclaration() = e else ref = e ) } -private SummaryComponent interpretComponent(string c) { - specSplit(_, c, _) and - ( - exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos)) - or - exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos)) - or - c = "ReturnValue" and result = SummaryComponent::return() - or - c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0)) - or - c = "Element" and result = SummaryComponent::content(any(CollectionContent c0)) - or - c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0)) - or - c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0)) - ) -} - -private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) { - exists(string c | - summaryElement(_, spec, _, _) or - summaryElement(_, _, spec, _) - | - len(spec, idx + 1) and - specSplit(spec, c, idx) and - stack = SummaryComponentStack::singleton(interpretComponent(c)) - ) - or - exists(SummaryComponent head, SummaryComponentStack tail | - interpretSpec(spec, idx, head, tail) and - stack = SummaryComponentStack::push(head, tail) - ) -} - -private predicate interpretSpec( - string output, int idx, SummaryComponent head, SummaryComponentStack tail -) { - exists(string c | - interpretSpec(output, idx + 1, tail) and - specSplit(output, c, idx) and - head = interpretComponent(c) - ) -} - -private class MkStack extends RequiredSummaryComponentStack { - MkStack() { interpretSpec(_, _, _, this) } - - override predicate required(SummaryComponent c) { interpretSpec(_, _, c, this) } -} - -private class SummarizedCallableExternal extends SummarizedCallable { - SummarizedCallableExternal() { summaryElement(this, _, _, _) } - - override predicate propagatesFlow( - SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - ) { - exists(string inSpec, string outSpec, string kind | - summaryElement(this, inSpec, outSpec, kind) and - interpretSpec(inSpec, 0, input) and - interpretSpec(outSpec, 0, output) - | - kind = "value" and preservesValue = true - or - kind = "taint" and preservesValue = false - ) - } -} - private newtype TAstOrNode = TAst(Top t) or TNode(Node n) @@ -795,7 +696,7 @@ private predicate interpretOutput(string output, int idx, Top ref, TAstOrNode no sourceElementRef(ref, output, _) or summaryElementRef(ref, _, output, _) ) and - len(output, idx) and + specLength(output, idx) and node = TAst(ref) or exists(Top mid, string c, Node n | @@ -827,7 +728,7 @@ private predicate interpretInput(string input, int idx, Top ref, TAstOrNode node sinkElementRef(ref, input, _) or summaryElementRef(ref, input, _, _) ) and - len(input, idx) and + specLength(input, idx) and node = TAst(ref) or exists(Top mid, string c, Node n | diff --git a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index bdf5498d8c6..da6f89071ef 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -580,88 +580,112 @@ module Private { * summaries into a `SummarizedCallable`s. */ module External { - /** - * Provides a means of translating an externally (e.g., CSV) defined flow - * summary into a `SummarizedCallable`. - */ - abstract class ExternalSummaryCompilation extends string { - bindingset[this] - ExternalSummaryCompilation() { any() } + /** Holds if the `n`th component of specification `s` is `c`. */ + predicate specSplit(string s, string c, int n) { relevantSpec(s) and s.splitAt(" of ", n) = c } - /** Holds if this flow summary is for callable `c`. */ - abstract predicate callable(DataFlowCallable c, boolean preservesValue); + /** Holds if specification `s` has length `len`. */ + predicate specLength(string s, int len) { len = 1 + max(int n | specSplit(s, _, n)) } - /** Holds if the `i`th input component is `c`. */ - abstract predicate input(int i, SummaryComponent c); - - /** Holds if the `i`th output component is `c`. */ - abstract predicate output(int i, SummaryComponent c); - - /** - * Holds if the input components starting from index `i` translate into `suffix`. - */ - final predicate translateInput(int i, SummaryComponentStack suffix) { - exists(SummaryComponent comp | this.input(i, comp) | - i = max(int j | this.input(j, _)) and - suffix = TSingletonSummaryComponentStack(comp) - or - exists(TSummaryComponent head, SummaryComponentStack tail | - this.translateInputCons(i, head, tail) and - suffix = TConsSummaryComponentStack(head, tail) - ) - ) - } - - final predicate translateInputCons(int i, SummaryComponent head, SummaryComponentStack tail) { - this.input(i, head) and - this.translateInput(i + 1, tail) - } - - /** - * Holds if the output components starting from index `i` translate into `suffix`. - */ - predicate translateOutput(int i, SummaryComponentStack suffix) { - exists(SummaryComponent comp | this.output(i, comp) | - i = max(int j | this.output(j, _)) and - suffix = TSingletonSummaryComponentStack(comp) - or - exists(TSummaryComponent head, SummaryComponentStack tail | - this.translateOutputCons(i, head, tail) and - suffix = TConsSummaryComponentStack(head, tail) - ) - ) - } - - predicate translateOutputCons(int i, SummaryComponent head, SummaryComponentStack tail) { - this.output(i, head) and - this.translateOutput(i + 1, tail) - } + /** Gets the last component of specification `s`. */ + string specLast(string s) { + exists(int len | + specLength(s, len) and + specSplit(s, result, len - 1) + ) } - private class ExternalRequiredSummaryComponentStack extends RequiredSummaryComponentStack { - private SummaryComponent head; - - ExternalRequiredSummaryComponentStack() { - any(ExternalSummaryCompilation s).translateInputCons(_, head, this) or - any(ExternalSummaryCompilation s).translateOutputCons(_, head, this) - } - - override predicate required(SummaryComponent c) { c = head } + /** Holds if specification component `c` parses as parameter `n`. */ + predicate parseParam(string c, int n) { + specSplit(_, c, _) and + ( + c.regexpCapture("Parameter\\[([-0-9]+)\\]", 1).toInt() = n + or + exists(int n1, int n2 | + c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and + c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and + n = [n1 .. n2] + ) + ) } - class ExternalSummarizedCallableAdaptor extends SummarizedCallable { - ExternalSummarizedCallableAdaptor() { any(ExternalSummaryCompilation s).callable(this, _) } + /** Holds if specification component `c` parses as argument `n`. */ + predicate parseArg(string c, int n) { + specSplit(_, c, _) and + ( + c.regexpCapture("Argument\\[([-0-9]+)\\]", 1).toInt() = n + or + exists(int n1, int n2 | + c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and + c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and + n = [n1 .. n2] + ) + ) + } + + private SummaryComponent interpretComponent(string c) { + specSplit(_, c, _) and + ( + exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos)) + or + exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos)) + or + result = interpretComponentSpecific(c) + ) + } + + private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) { + exists(string c | + relevantSpec(spec) and + specLength(spec, idx + 1) and + specSplit(spec, c, idx) and + stack = SummaryComponentStack::singleton(interpretComponent(c)) + ) + or + exists(SummaryComponent head, SummaryComponentStack tail | + interpretSpec(spec, idx, head, tail) and + stack = SummaryComponentStack::push(head, tail) + ) + } + + private predicate interpretSpec( + string output, int idx, SummaryComponent head, SummaryComponentStack tail + ) { + exists(string c | + interpretSpec(output, idx + 1, tail) and + specSplit(output, c, idx) and + head = interpretComponent(c) + ) + } + + private class MkStack extends RequiredSummaryComponentStack { + MkStack() { interpretSpec(_, _, _, this) } + + override predicate required(SummaryComponent c) { interpretSpec(_, _, c, this) } + } + + private class SummarizedCallableExternal extends SummarizedCallable { + SummarizedCallableExternal() { externalSummary(this, _, _, _) } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists(ExternalSummaryCompilation s | - s.callable(this, preservesValue) and - s.translateInput(0, input) and - s.translateOutput(0, output) + exists(string inSpec, string outSpec, string kind | + externalSummary(this, inSpec, outSpec, kind) and + interpretSpec(inSpec, 0, input) and + interpretSpec(outSpec, 0, output) + | + kind = "value" and preservesValue = true + or + kind = "taint" and preservesValue = false ) } } + + /** Holds if component `c` of specification `spec` cannot be parsed. */ + predicate invalidSpecComponent(string spec, string c) { + specSplit(spec, c, _) and + not exists(interpretComponent(c)) + } } /** Provides a query predicate for outputting a set of relevant flow summaries. */ diff --git a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index dae0571f0fa..327ddfb50dd 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -7,6 +7,7 @@ private import DataFlowPrivate private import DataFlowUtil private import FlowSummaryImpl::Private private import FlowSummaryImpl::Public +private import semmle.code.java.dataflow.ExternalFlow private module FlowSummaries { private import semmle.code.java.dataflow.FlowSummary as F @@ -49,3 +50,28 @@ DataFlowType getCallbackParameterType(DataFlowType t, int i) { none() } * callback of type `t`. */ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } + +/** Holds if `spec` is a relevant external specification. */ +predicate relevantSpec(string spec) { spec = inOutSpec() } + +/** + * Holds if an external flow summary exists for `c` with input specification + * `input`, output specification `output`, and kind `kind`. + */ +predicate externalSummary(DataFlowCallable c, string input, string output, string kind) { + summaryElement(c, input, output, kind) +} + +/** Gets the summary component for specification component `c`, if any. */ +bindingset[c] +SummaryComponent interpretComponentSpecific(string c) { + c = "ReturnValue" and result = SummaryComponent::return(_) + or + c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0)) + or + c = "Element" and result = SummaryComponent::content(any(CollectionContent c0)) + or + c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0)) + or + c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0)) +} From ecf7f24cde1a3b721f006733e6a5f57878c55f1e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 1 Jun 2021 13:09:27 +0200 Subject: [PATCH 078/272] C#: Sync latest `FlowSummaryImpl.qll` changes --- .../dataflow/internal/FlowSummaryImpl.qll | 162 ++++++++++-------- .../internal/FlowSummaryImplSpecific.qll | 27 +++ 2 files changed, 120 insertions(+), 69 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index bdf5498d8c6..da6f89071ef 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -580,88 +580,112 @@ module Private { * summaries into a `SummarizedCallable`s. */ module External { - /** - * Provides a means of translating an externally (e.g., CSV) defined flow - * summary into a `SummarizedCallable`. - */ - abstract class ExternalSummaryCompilation extends string { - bindingset[this] - ExternalSummaryCompilation() { any() } + /** Holds if the `n`th component of specification `s` is `c`. */ + predicate specSplit(string s, string c, int n) { relevantSpec(s) and s.splitAt(" of ", n) = c } - /** Holds if this flow summary is for callable `c`. */ - abstract predicate callable(DataFlowCallable c, boolean preservesValue); + /** Holds if specification `s` has length `len`. */ + predicate specLength(string s, int len) { len = 1 + max(int n | specSplit(s, _, n)) } - /** Holds if the `i`th input component is `c`. */ - abstract predicate input(int i, SummaryComponent c); - - /** Holds if the `i`th output component is `c`. */ - abstract predicate output(int i, SummaryComponent c); - - /** - * Holds if the input components starting from index `i` translate into `suffix`. - */ - final predicate translateInput(int i, SummaryComponentStack suffix) { - exists(SummaryComponent comp | this.input(i, comp) | - i = max(int j | this.input(j, _)) and - suffix = TSingletonSummaryComponentStack(comp) - or - exists(TSummaryComponent head, SummaryComponentStack tail | - this.translateInputCons(i, head, tail) and - suffix = TConsSummaryComponentStack(head, tail) - ) - ) - } - - final predicate translateInputCons(int i, SummaryComponent head, SummaryComponentStack tail) { - this.input(i, head) and - this.translateInput(i + 1, tail) - } - - /** - * Holds if the output components starting from index `i` translate into `suffix`. - */ - predicate translateOutput(int i, SummaryComponentStack suffix) { - exists(SummaryComponent comp | this.output(i, comp) | - i = max(int j | this.output(j, _)) and - suffix = TSingletonSummaryComponentStack(comp) - or - exists(TSummaryComponent head, SummaryComponentStack tail | - this.translateOutputCons(i, head, tail) and - suffix = TConsSummaryComponentStack(head, tail) - ) - ) - } - - predicate translateOutputCons(int i, SummaryComponent head, SummaryComponentStack tail) { - this.output(i, head) and - this.translateOutput(i + 1, tail) - } + /** Gets the last component of specification `s`. */ + string specLast(string s) { + exists(int len | + specLength(s, len) and + specSplit(s, result, len - 1) + ) } - private class ExternalRequiredSummaryComponentStack extends RequiredSummaryComponentStack { - private SummaryComponent head; - - ExternalRequiredSummaryComponentStack() { - any(ExternalSummaryCompilation s).translateInputCons(_, head, this) or - any(ExternalSummaryCompilation s).translateOutputCons(_, head, this) - } - - override predicate required(SummaryComponent c) { c = head } + /** Holds if specification component `c` parses as parameter `n`. */ + predicate parseParam(string c, int n) { + specSplit(_, c, _) and + ( + c.regexpCapture("Parameter\\[([-0-9]+)\\]", 1).toInt() = n + or + exists(int n1, int n2 | + c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and + c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and + n = [n1 .. n2] + ) + ) } - class ExternalSummarizedCallableAdaptor extends SummarizedCallable { - ExternalSummarizedCallableAdaptor() { any(ExternalSummaryCompilation s).callable(this, _) } + /** Holds if specification component `c` parses as argument `n`. */ + predicate parseArg(string c, int n) { + specSplit(_, c, _) and + ( + c.regexpCapture("Argument\\[([-0-9]+)\\]", 1).toInt() = n + or + exists(int n1, int n2 | + c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and + c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and + n = [n1 .. n2] + ) + ) + } + + private SummaryComponent interpretComponent(string c) { + specSplit(_, c, _) and + ( + exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos)) + or + exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos)) + or + result = interpretComponentSpecific(c) + ) + } + + private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) { + exists(string c | + relevantSpec(spec) and + specLength(spec, idx + 1) and + specSplit(spec, c, idx) and + stack = SummaryComponentStack::singleton(interpretComponent(c)) + ) + or + exists(SummaryComponent head, SummaryComponentStack tail | + interpretSpec(spec, idx, head, tail) and + stack = SummaryComponentStack::push(head, tail) + ) + } + + private predicate interpretSpec( + string output, int idx, SummaryComponent head, SummaryComponentStack tail + ) { + exists(string c | + interpretSpec(output, idx + 1, tail) and + specSplit(output, c, idx) and + head = interpretComponent(c) + ) + } + + private class MkStack extends RequiredSummaryComponentStack { + MkStack() { interpretSpec(_, _, _, this) } + + override predicate required(SummaryComponent c) { interpretSpec(_, _, c, this) } + } + + private class SummarizedCallableExternal extends SummarizedCallable { + SummarizedCallableExternal() { externalSummary(this, _, _, _) } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists(ExternalSummaryCompilation s | - s.callable(this, preservesValue) and - s.translateInput(0, input) and - s.translateOutput(0, output) + exists(string inSpec, string outSpec, string kind | + externalSummary(this, inSpec, outSpec, kind) and + interpretSpec(inSpec, 0, input) and + interpretSpec(outSpec, 0, output) + | + kind = "value" and preservesValue = true + or + kind = "taint" and preservesValue = false ) } } + + /** Holds if component `c` of specification `spec` cannot be parsed. */ + predicate invalidSpecComponent(string spec, string c) { + specSplit(spec, c, _) and + not exists(interpretComponent(c)) + } } /** Provides a query predicate for outputting a set of relevant flow summaries. */ diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 01e3a2e1633..5568b8d3368 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -77,3 +77,30 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { result = Gvn::getGlobalValueNumber(dt.getDelegateType().getReturnType()) ) } + +/** Holds if `spec` is a relevant external specification. */ +predicate relevantSpec(string spec) { none() } + +/** + * Holds if an external flow summary exists for `c` with input specification + * `input`, output specification `output`, and kind `kind`. + */ +predicate externalSummary(DataFlowCallable c, string input, string output, string kind) { none() } + +/** Gets the summary component for specification component `c`, if any. */ +bindingset[c] +SummaryComponent interpretComponentSpecific(string c) { + c = "ReturnValue" and result = SummaryComponent::return(any(NormalReturnKind nrk)) + or + c = "Element" and result = SummaryComponent::content(any(ElementContent ec)) + or + exists(Field f | + c.regexpCapture("Field\\[(.+)\\]", 1) = f.getQualifiedName() and + result = SummaryComponent::content(any(FieldContent fc | fc.getField() = f)) + ) + or + exists(Property p | + c.regexpCapture("Property\\[(.+)\\]", 1) = p.getQualifiedName() and + result = SummaryComponent::content(any(PropertyContent pc | pc.getProperty() = p)) + ) +} From 0fb692400cff3f22a2929f673da18b4b91379b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Tue, 1 Jun 2021 13:57:13 +0200 Subject: [PATCH 079/272] fix failing test --- .../Security/CWE/CWE-209/StackTraceExposure.ql | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index b82edc2efc6..4f2753b9723 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -109,7 +109,7 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) { /** * A stringified stack trace flows to an external sink. */ -predicate stringifiedStackFlowsExternally(XssSink externalExpr, Expr stackTrace) { +predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stackTrace) { exists(MethodAccess stackTraceString, StackTraceStringToHTTPResponseSinkFlowConfig conf | stackTraceExpr(stackTrace, stackTraceString) and conf.hasFlow(DataFlow::exprNode(stackTraceString), externalExpr) @@ -127,21 +127,24 @@ class GetMessageFlowSource extends MethodAccess { } } -class GetMessageFlowSourceToXssSinkFlowConfig extends TaintTracking::Configuration { - GetMessageFlowSourceToXssSinkFlowConfig() { - this = "StackTraceExposure::GetMessageFlowSourceToXssSinkFlowConfig" +class GetMessageFlowSourceToHTTPResponseSinkFlowConfig extends TaintTracking::Configuration { + GetMessageFlowSourceToHTTPResponseSinkFlowConfig() { + this = "StackTraceExposure::GetMessageFlowSourceToHTTPResponseSinkFlowConfig" } override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof GetMessageFlowSource } - override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } + override predicate isSink(DataFlow::Node sink) { + sink instanceof XssSink or + sink instanceof InformationLeakSink + } } /** * A call to `getMessage()` that then flows to a servlet response. */ -predicate getMessageFlowsExternally(XssSink externalExpr, GetMessageFlowSource getMessage) { - any(GetMessageFlowSourceToXssSinkFlowConfig conf) +predicate getMessageFlowsExternally(DataFlow::Node externalExpr, GetMessageFlowSource getMessage) { + any(GetMessageFlowSourceToHTTPResponseSinkFlowConfig conf) .hasFlow(DataFlow::exprNode(getMessage), externalExpr) } From 1c081eeaedb27332623e67231bf21c1f5d8a62d5 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 1 Jun 2021 13:51:16 +0200 Subject: [PATCH 080/272] Java: Update coverage. --- .../library-coverage/flow-model-coverage.csv | 18 +++++++++--------- .../library-coverage/flow-model-coverage.rst | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/java/documentation/library-coverage/flow-model-coverage.csv b/java/documentation/library-coverage/flow-model-coverage.csv index cf97071ad92..a66f7880221 100644 --- a/java/documentation/library-coverage/flow-model-coverage.csv +++ b/java/documentation/library-coverage/flow-model-coverage.csv @@ -3,16 +3,16 @@ android.util,,16,,,,,,,,,,,16,, android.webkit,3,2,,,,,,,,,,3,2,, com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,1, com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,2,,,,,,,,,,,2, -com.google.common.base,,,28,,,,,,,,,,,22,6 -com.google.common.io,6,,69,,,,,,,6,,,,68,1 +com.fasterxml.jackson.databind,,,3,,,,,,,,,,,3, +com.google.common.base,,,34,,,,,,,,,,,28,6 +com.google.common.io,6,,73,,,,,,,6,,,,72,1 com.unboundid.ldap.sdk,17,,,,,,17,,,,,,,, java.beans,,,1,,,,,,,,,,,1, java.io,3,,20,,3,,,,,,,,,20, -java.lang,,,1,,,,,,,,,,,1, +java.lang,,,3,,,,,,,,,,,1,2 java.net,2,3,4,,,,,2,,,,,3,4, java.nio,10,,2,,10,,,,,,,,,2, -java.util,,,13,,,,,,,,,,,13, +java.util,,,283,,,,,,,,,,,15,268 javax.naming.directory,1,,,,,,1,,,,,,,, javax.net.ssl,2,,,,,,,,2,,,,,, javax.servlet,4,21,2,,,3,,,,,,1,21,2, @@ -23,14 +23,14 @@ javax.xml.transform.stream,,,2,,,,,,,,,,,2, javax.xml.xpath,3,,,,,,,,,,3,,,, org.apache.commons.codec,,,2,,,,,,,,,,,2, org.apache.commons.io,,,22,,,,,,,,,,,22, -org.apache.commons.lang3,,,313,,,,,,,,,,,299,14 -org.apache.commons.text,,,203,,,,,,,,,,,203, +org.apache.commons.lang3,,,327,,,,,,,,,,,311,16 +org.apache.commons.text,,,220,,,,,,,,,,,220, org.apache.directory.ldap.client.api,1,,,,,,1,,,,,,,, org.apache.hc.core5.function,,,1,,,,,,,,,,,1, org.apache.hc.core5.http,1,2,39,,,,,,,,,1,2,39, org.apache.hc.core5.net,,,2,,,,,,,,,,,2, -org.apache.hc.core5.util,,,22,,,,,,,,,,,18,4 -org.apache.http,2,3,66,,,,,,,,,2,3,59,7 +org.apache.hc.core5.util,,,24,,,,,,,,,,,18,6 +org.apache.http,2,3,67,,,,,,,,,2,3,59,8 org.dom4j,20,,,,,,,,,,20,,,, org.springframework.ldap.core,14,,,,,,14,,,,,,,, org.springframework.security.web.savedrequest,,6,,,,,,,,,,,6,, diff --git a/java/documentation/library-coverage/flow-model-coverage.rst b/java/documentation/library-coverage/flow-model-coverage.rst index 8bb20a9b6c3..6e46c906b07 100644 --- a/java/documentation/library-coverage/flow-model-coverage.rst +++ b/java/documentation/library-coverage/flow-model-coverage.rst @@ -8,12 +8,12 @@ Java framework & library support Framework / library,Package,Remote flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` Android,``android.*``,18,,3,,,3,,,, - Apache,``org.apache.*``,5,648,4,,,3,,1,, + Apache,``org.apache.*``,5,682,4,,,3,,1,, `Apache Commons IO `_,``org.apache.commons.io``,,22,,,,,,,, - Google,``com.google.common.*``,,97,6,,6,,,,, - Java Standard Library,``java.*``,3,41,15,13,,,,,,2 + Google,``com.google.common.*``,,107,6,,6,,,,, + Java Standard Library,``java.*``,3,313,15,13,,,,,,2 Java extensions,``javax.*``,22,8,12,,,1,,1,1, `Spring `_,``org.springframework.*``,29,,14,,,,,14,, - Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.dom4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,5,37,,,,,17,, - Totals,,84,821,91,13,6,7,,33,1,2 + Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.dom4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,6,37,,,,,17,, + Totals,,84,1138,91,13,6,7,,33,1,2 From 922b421a45388be29efdb5d91b2031add1133df4 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 1 Jun 2021 14:33:52 +0200 Subject: [PATCH 081/272] Java: Add change note. --- java/change-notes/2021-06-01-collection-flow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 java/change-notes/2021-06-01-collection-flow.md diff --git a/java/change-notes/2021-06-01-collection-flow.md b/java/change-notes/2021-06-01-collection-flow.md new file mode 100644 index 00000000000..5da2e78d1df --- /dev/null +++ b/java/change-notes/2021-06-01-collection-flow.md @@ -0,0 +1,5 @@ +lgtm,codescanning +* Data flow now tracks steps through collections and arrays more precisely. + That means that collection and array read steps are now matched up with + preceding store steps. This results in increased precision for all flow-based + queries, in particular most of the security queries. From 970b4e7d6a49a95f6d6a5577cd7ac315065f5553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Tue, 1 Jun 2021 14:54:31 +0200 Subject: [PATCH 082/272] update java library coverage documentation --- .../library-coverage/flow-model-coverage.csv | 84 +++++++++---------- .../library-coverage/flow-model-coverage.rst | 4 +- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/java/documentation/library-coverage/flow-model-coverage.csv b/java/documentation/library-coverage/flow-model-coverage.csv index 73f06306193..464228bb022 100644 --- a/java/documentation/library-coverage/flow-model-coverage.csv +++ b/java/documentation/library-coverage/flow-model-coverage.csv @@ -1,42 +1,42 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:header-splitting,sink:ldap,sink:open-url,sink:set-hostname-verifier,sink:url-open-stream,sink:xpath,sink:xss,source:remote,summary:taint,summary:value -android.util,,16,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,3,2,, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,2,,,,,,,,,,,2, -com.google.common.base,,,28,,,,,,,,,,,22,6 -com.google.common.io,6,,69,,,,,,,6,,,,68,1 -com.unboundid.ldap.sdk,17,,,,,,17,,,,,,,, -java.beans,,,1,,,,,,,,,,,1, -java.io,3,,20,,3,,,,,,,,,20, -java.lang,,,1,,,,,,,,,,,1, -java.net,2,3,4,,,,,2,,,,,3,4, -java.nio,10,,2,,10,,,,,,,,,2, -java.util,,,13,,,,,,,,,,,13, -javax.naming.directory,1,,,,,,1,,,,,,,, -javax.net.ssl,2,,,,,,,,2,,,,,, -javax.servlet,3,21,2,,,3,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,1,, -javax.ws.rs.core,1,,,,,1,,,,,,,,, -javax.xml.transform.sax,,,4,,,,,,,,,,,4, -javax.xml.transform.stream,,,2,,,,,,,,,,,2, -javax.xml.xpath,3,,,,,,,,,,3,,,, -org.apache.commons.codec,,,2,,,,,,,,,,,2, -org.apache.commons.io,,,22,,,,,,,,,,,22, -org.apache.commons.lang3,,,313,,,,,,,,,,,299,14 -org.apache.commons.text,,,203,,,,,,,,,,,203, -org.apache.directory.ldap.client.api,1,,,,,,1,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,1,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,2, -org.apache.hc.core5.util,,,22,,,,,,,,,,,18,4 -org.apache.http,2,3,66,,,,,,,,,2,3,59,7 -org.dom4j,20,,,,,,,,,,20,,,, -org.springframework.ldap.core,14,,,,,,14,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,6,, -org.springframework.web.client,,3,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,,,,,,,,,,,12,, -org.xml.sax,,,1,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,4,, +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:header-splitting,sink:information-leak,sink:ldap,sink:open-url,sink:set-hostname-verifier,sink:url-open-stream,sink:xpath,sink:xss,source:remote,summary:taint,summary:value +android.util,,16,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,3,2,, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,2,,,,,,,,,,,,2, +com.google.common.base,,,28,,,,,,,,,,,,22,6 +com.google.common.io,6,,69,,,,,,,,6,,,,68,1 +com.unboundid.ldap.sdk,17,,,,,,,17,,,,,,,, +java.beans,,,1,,,,,,,,,,,,1, +java.io,3,,20,,3,,,,,,,,,,20, +java.lang,,,1,,,,,,,,,,,,1, +java.net,2,3,4,,,,,,2,,,,,3,4, +java.nio,10,,2,,10,,,,,,,,,,2, +java.util,,,13,,,,,,,,,,,,13, +javax.naming.directory,1,,,,,,,1,,,,,,,, +javax.net.ssl,2,,,,,,,,,2,,,,,, +javax.servlet,4,21,2,,,3,1,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,1,, +javax.ws.rs.core,1,,,,,1,,,,,,,,,, +javax.xml.transform.sax,,,4,,,,,,,,,,,,4, +javax.xml.transform.stream,,,2,,,,,,,,,,,,2, +javax.xml.xpath,3,,,,,,,,,,,3,,,, +org.apache.commons.codec,,,2,,,,,,,,,,,,2, +org.apache.commons.io,,,22,,,,,,,,,,,,22, +org.apache.commons.lang3,,,313,,,,,,,,,,,,299,14 +org.apache.commons.text,,,203,,,,,,,,,,,,203, +org.apache.directory.ldap.client.api,1,,,,,,,1,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,1,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,22,,,,,,,,,,,,18,4 +org.apache.http,2,3,66,,,,,,,,,,2,3,59,7 +org.dom4j,20,,,,,,,,,,,20,,,, +org.springframework.ldap.core,14,,,,,,,14,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,6,, +org.springframework.web.client,,3,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,,,,,,,,,,,,12,, +org.xml.sax,,,1,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,4,, diff --git a/java/documentation/library-coverage/flow-model-coverage.rst b/java/documentation/library-coverage/flow-model-coverage.rst index bad79a93c06..b9b54aad158 100644 --- a/java/documentation/library-coverage/flow-model-coverage.rst +++ b/java/documentation/library-coverage/flow-model-coverage.rst @@ -12,8 +12,8 @@ Java framework & library support `Apache Commons IO `_,``org.apache.commons.io``,,22,,,,,,,, Google,``com.google.common.*``,,97,6,,6,,,,, Java Standard Library,``java.*``,3,41,15,13,,,,,,2 - Java extensions,``javax.*``,22,8,11,,,,,1,1, + Java extensions,``javax.*``,22,8,12,,,,,1,1, `Spring `_,``org.springframework.*``,29,,14,,,,,14,, Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.dom4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,5,37,,,,,17,, - Totals,,84,821,90,13,6,6,,33,1,2 + Totals,,84,821,91,13,6,6,,33,1,2 From 650c4f19d2088b446523b3ec29ed3aae13ccad72 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 1 Jun 2021 16:09:17 +0200 Subject: [PATCH 083/272] Java: More qldoc. --- .../code/java/dataflow/internal/ContainerFlow.qll | 14 ++++++++++++++ .../java/dataflow/internal/TaintTrackingUtil.qll | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll index 667ae024b37..d57c68bf007 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -710,6 +710,11 @@ predicate containerStep(Expr n1, Expr n2) { containerUpdateStep(n1, n2) } +/** + * Holds if the step from `node1` to `node2` stores a value in an array. + * This covers array assignments and initializers as well as implicit array + * creations for varargs. + */ predicate arrayStoreStep(Node node1, Node node2) { exists(Argument arg | node1.asExpr() = arg and @@ -734,6 +739,11 @@ private predicate enhancedForStmtStep(Node node1, Node node2, Type containerType ) } +/** + * Holds if the step from `node1` to `node2` reads a value from an array. + * This covers ordinary array reads as well as array iteration through enhanced + * `for` statements. + */ predicate arrayReadStep(Node node1, Node node2, Type elemType) { exists(ArrayAccess aa | aa.getArray() = node1.asExpr() and @@ -747,6 +757,10 @@ predicate arrayReadStep(Node node1, Node node2, Type elemType) { ) } +/** + * Holds if the step from `node1` to `node2` reads a value from a collection. + * This only covers iteration through enhanced `for` statements. + */ predicate collectionReadStep(Node node1, Node node2) { enhancedForStmtStep(node1, node2, any(Type t | not t instanceof Array)) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 719b89fbf2a..d2322eca983 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -98,6 +98,17 @@ private module Cached { import Cached +/** + * These configurations add a number of configuration-dependent additional taint + * steps to all taint configurations. For each sink or additional step provided + * by a given configuration the types are inspected to find those implicit + * collection or array read steps that might be required at the sink or step + * input. The corresponding store steps are then added as additional taint steps + * to provide backwards-compatible taint flow to such sinks and steps. + * + * This is a temporary measure until support is added for such sinks that + * require implicit read steps. + */ private module StoreTaintSteps { private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.dataflow.TaintTracking2 From 9aba92397dbc686eb15e83e0df401d8eb7299606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Tue, 1 Jun 2021 17:16:41 +0200 Subject: [PATCH 084/272] lift XssSink check to InformationLeakSink --- .../ql/src/Security/CWE/CWE-209/StackTraceExposure.ql | 11 ++--------- .../src/semmle/code/java/security/InformationLeak.qll | 6 +++++- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index 4f2753b9723..78a6b9108e3 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -15,7 +15,6 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.security.XSS import semmle.code.java.security.InformationLeak /** @@ -91,10 +90,7 @@ class StackTraceStringToHTTPResponseSinkFlowConfig extends TaintTracking::Config override predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) } - override predicate isSink(DataFlow::Node sink) { - sink instanceof XssSink or - sink instanceof InformationLeakSink - } + override predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink } } /** @@ -134,10 +130,7 @@ class GetMessageFlowSourceToHTTPResponseSinkFlowConfig extends TaintTracking::Co override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof GetMessageFlowSource } - override predicate isSink(DataFlow::Node sink) { - sink instanceof XssSink or - sink instanceof InformationLeakSink - } + override predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink } } /** diff --git a/java/ql/src/semmle/code/java/security/InformationLeak.qll b/java/ql/src/semmle/code/java/security/InformationLeak.qll index 4cb12c3d3d9..f68ddd5b121 100644 --- a/java/ql/src/semmle/code/java/security/InformationLeak.qll +++ b/java/ql/src/semmle/code/java/security/InformationLeak.qll @@ -3,6 +3,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.security.XSS /** CSV sink models representing methods not susceptible to XSS but outputing to an HTTP response body. */ private class DefaultInformationLeakSinkModel extends SinkModelCsv { @@ -19,5 +20,8 @@ abstract class InformationLeakSink extends DataFlow::Node { } /** A default sink representing methods outputing data to an HTTP response. */ private class DefaultInformationLeakSink extends InformationLeakSink { - DefaultInformationLeakSink() { sinkNode(this, "information-leak") } + DefaultInformationLeakSink() { + sinkNode(this, "information-leak") or + this instanceof XssSink + } } From 5e96e28792037cb8a289bab7c6c47f16342f7c4e Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 2 Jun 2021 10:24:46 +0200 Subject: [PATCH 085/272] Java: Add missing metadata. --- .../ql/src/experimental/Security/CWE/CWE-094/JythonInjection.ql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JythonInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-094/JythonInjection.ql index c44eee23602..c6a7f583b14 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/JythonInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JythonInjection.ql @@ -3,6 +3,8 @@ * @description Evaluation of a user-controlled malicious expression in Java Python * interpreter may lead to remote code execution. * @kind path-problem + * @problem.severity error + * @precision high * @id java/jython-injection * @tags security * external/cwe/cwe-094 From a3a215afea122df02b5a52bb2ff21e7c45affb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mun=CC=83oz?= Date: Wed, 2 Jun 2021 11:12:39 +0200 Subject: [PATCH 086/272] HTTP -> Http --- .../Security/CWE/CWE-209/StackTraceExposure.ql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index 78a6b9108e3..233e2694afa 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -83,9 +83,9 @@ predicate stackTraceExpr(Expr exception, MethodAccess stackTraceString) { ) } -class StackTraceStringToHTTPResponseSinkFlowConfig extends TaintTracking::Configuration { - StackTraceStringToHTTPResponseSinkFlowConfig() { - this = "StackTraceExposure::StackTraceStringToHTTPResponseSinkFlowConfig" +class StackTraceStringToHttpResponseSinkFlowConfig extends TaintTracking::Configuration { + StackTraceStringToHttpResponseSinkFlowConfig() { + this = "StackTraceExposure::StackTraceStringToHttpResponseSinkFlowConfig" } override predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) } @@ -106,7 +106,7 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) { * A stringified stack trace flows to an external sink. */ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stackTrace) { - exists(MethodAccess stackTraceString, StackTraceStringToHTTPResponseSinkFlowConfig conf | + exists(MethodAccess stackTraceString, StackTraceStringToHttpResponseSinkFlowConfig conf | stackTraceExpr(stackTrace, stackTraceString) and conf.hasFlow(DataFlow::exprNode(stackTraceString), externalExpr) ) @@ -123,9 +123,9 @@ class GetMessageFlowSource extends MethodAccess { } } -class GetMessageFlowSourceToHTTPResponseSinkFlowConfig extends TaintTracking::Configuration { - GetMessageFlowSourceToHTTPResponseSinkFlowConfig() { - this = "StackTraceExposure::GetMessageFlowSourceToHTTPResponseSinkFlowConfig" +class GetMessageFlowSourceToHttpResponseSinkFlowConfig extends TaintTracking::Configuration { + GetMessageFlowSourceToHttpResponseSinkFlowConfig() { + this = "StackTraceExposure::GetMessageFlowSourceToHttpResponseSinkFlowConfig" } override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof GetMessageFlowSource } @@ -137,7 +137,7 @@ class GetMessageFlowSourceToHTTPResponseSinkFlowConfig extends TaintTracking::Co * A call to `getMessage()` that then flows to a servlet response. */ predicate getMessageFlowsExternally(DataFlow::Node externalExpr, GetMessageFlowSource getMessage) { - any(GetMessageFlowSourceToHTTPResponseSinkFlowConfig conf) + any(GetMessageFlowSourceToHttpResponseSinkFlowConfig conf) .hasFlow(DataFlow::exprNode(getMessage), externalExpr) } From f9ede137f9fc86548fdc24af45034f4b317f70a4 Mon Sep 17 00:00:00 2001 From: AlonaHlobina <54394529+AlonaHlobina@users.noreply.github.com> Date: Wed, 2 Jun 2021 14:19:18 +0200 Subject: [PATCH 087/272] Update versions-compilers.rst --- docs/codeql/support/reusables/versions-compilers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/support/reusables/versions-compilers.rst index 9bc3c855e58..330922fd876 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/support/reusables/versions-compilers.rst @@ -17,11 +17,11 @@ .NET 5","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" Go (aka Golang), "Go up to 1.16", "Go 1.11 or more recent", ``.go`` - Java,"Java 7 to 15 [3]_","javac (OpenJDK and Oracle JDK), + Java,"Java 7 to 15 [3]_, Java 16 (partially)","javac (OpenJDK and Oracle JDK), Eclipse compiler for Java (ECJ) [4]_",``.java`` JavaScript,ECMAScript 2021 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhm``, ``.xhtml``, ``.vue``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [5]_" - Python,"2.7, 3.5, 3.6, 3.7, 3.8",Not applicable,``.py`` + Python,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9",Not applicable,``.py`` TypeScript [6]_,"2.6-4.2",Standard TypeScript compiler,"``.ts``, ``.tsx``" .. container:: footnote-group From 788c5ba70124c4f766c1c49d1217f612ca63da11 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 15:33:08 +0200 Subject: [PATCH 088/272] add support for the prettier API --- javascript/ql/src/javascript.qll | 1 + .../semmle/javascript/frameworks/Prettier.qll | 52 +++++++++++++++++++ .../CWE-022/TaintedPath/TaintedPath.expected | 45 ++++++++++++++++ .../Security/CWE-022/TaintedPath/prettier.js | 14 +++++ .../ReflectedXss/ReflectedXss.expected | 12 +++++ .../ReflectedXssWithCustomSanitizer.expected | 1 + .../Security/CWE-079/ReflectedXss/tst3.js | 6 +++ 7 files changed, 131 insertions(+) create mode 100644 javascript/ql/src/semmle/javascript/frameworks/Prettier.qll create mode 100644 javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/prettier.js diff --git a/javascript/ql/src/javascript.qll b/javascript/ql/src/javascript.qll index 95db948bbd4..e3b202bf89b 100644 --- a/javascript/ql/src/javascript.qll +++ b/javascript/ql/src/javascript.qll @@ -104,6 +104,7 @@ import semmle.javascript.frameworks.Nest import semmle.javascript.frameworks.Next import semmle.javascript.frameworks.NoSQL import semmle.javascript.frameworks.PkgCloud +import semmle.javascript.frameworks.Prettier import semmle.javascript.frameworks.PropertyProjection import semmle.javascript.frameworks.Puppeteer import semmle.javascript.frameworks.React diff --git a/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll b/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll new file mode 100644 index 00000000000..eeb8d1cdb87 --- /dev/null +++ b/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll @@ -0,0 +1,52 @@ +/** + * Provides classes and predicates for working with the [prettier](https://www.npmjs.com/package/prettier) library. + */ + +import javascript + +/** Provides classes and predicates modelling aspects of the [prettier](https://www.npmjs.com/package/prettier) library. */ +private module Prettier { + /** + * A taint step from the [prettier API](https://prettier.io/docs/en/api.html). + */ + private class PrettierTaintStep extends TaintTracking::SharedTaintStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + exists(API::CallNode call | + call = API::moduleImport("prettier").getMember("format").getACall() + | + pred = call.getArgument(0) and + succ = call + ) + or + exists(API::CallNode call | + call = API::moduleImport("prettier").getMember("formatWithCursor").getACall() + | + pred = call.getArgument(0) and + succ = call.getReturn().getMember("formatted").getAnImmediateUse() + ) + } + } + + private import semmle.javascript.security.dataflow.TaintedPathCustomizations::TaintedPath as TaintedPath + + /** + * An argument given to the `prettier` library specificing the location of a config file. + */ + private class PrettierFileSink extends TaintedPath::Sink { + PrettierFileSink() { + this = + API::moduleImport("prettier") + .getMember(["resolveConfig", "resolveConfigFile", "getFileInfo"]) + .getACall() + .getArgument(0) + or + this = + API::moduleImport("prettier") + .getMember("resolveConfig") + .getACall() + .getParameter(1) + .getMember("config") + .getARhs() + } + } +} diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 5d8806c0501..24beed4007f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -2271,6 +2271,25 @@ nodes | other-fs-libraries.js:52:24:52:27 | path | | other-fs-libraries.js:52:24:52:27 | path | | other-fs-libraries.js:52:24:52:27 | path | +| prettier.js:6:11:6:28 | p | +| prettier.js:6:11:6:28 | p | +| prettier.js:6:11:6:28 | p | +| prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | +| prettier.js:6:13:6:13 | p | +| prettier.js:6:13:6:13 | p | +| prettier.js:6:13:6:13 | p | +| prettier.js:6:13:6:13 | p | +| prettier.js:7:28:7:28 | p | +| prettier.js:7:28:7:28 | p | +| prettier.js:7:28:7:28 | p | +| prettier.js:7:28:7:28 | p | +| prettier.js:7:28:7:28 | p | +| prettier.js:11:44:11:44 | p | +| prettier.js:11:44:11:44 | p | +| prettier.js:11:44:11:44 | p | +| prettier.js:11:44:11:44 | p | +| prettier.js:11:44:11:44 | p | | pupeteer.js:5:9:5:71 | tainted | | pupeteer.js:5:9:5:71 | tainted | | pupeteer.js:5:9:5:71 | tainted | @@ -6668,6 +6687,30 @@ edges | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | +| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p | | pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | | pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | | pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted | @@ -8295,6 +8338,8 @@ edges | other-fs-libraries.js:42:53:42:56 | path | other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:42:53:42:56 | path | This path depends on $@. | other-fs-libraries.js:38:24:38:30 | req.url | a user-provided value | | other-fs-libraries.js:51:19:51:22 | path | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:51:19:51:22 | path | This path depends on $@. | other-fs-libraries.js:49:24:49:30 | req.url | a user-provided value | | other-fs-libraries.js:52:24:52:27 | path | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:52:24:52:27 | path | This path depends on $@. | other-fs-libraries.js:49:24:49:30 | req.url | a user-provided value | +| prettier.js:7:28:7:28 | p | prettier.js:6:13:6:13 | p | prettier.js:7:28:7:28 | p | This path depends on $@. | prettier.js:6:13:6:13 | p | a user-provided value | +| prettier.js:11:44:11:44 | p | prettier.js:6:13:6:13 | p | prettier.js:11:44:11:44 | p | This path depends on $@. | prettier.js:6:13:6:13 | p | a user-provided value | | pupeteer.js:9:28:9:34 | tainted | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:9:28:9:34 | tainted | This path depends on $@. | pupeteer.js:5:28:5:53 | parseTo ... t).name | a user-provided value | | pupeteer.js:13:37:13:43 | tainted | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:13:37:13:43 | tainted | This path depends on $@. | pupeteer.js:5:28:5:53 | parseTo ... t).name | a user-provided value | | tainted-access-paths.js:8:19:8:22 | path | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:8:19:8:22 | path | This path depends on $@. | tainted-access-paths.js:6:24:6:30 | req.url | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/prettier.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/prettier.js new file mode 100644 index 00000000000..7546bb2c293 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/prettier.js @@ -0,0 +1,14 @@ +const express = require('express'); +const prettier = require("prettier"); + +const app = express(); +app.get('/some/path', function (req, res) { + const { p } = req.params; + prettier.resolveConfig(p).then((options) => { // NOT OK + const formatted = prettier.format("foo", options); + }); + + prettier.resolveConfig("foo", {config: p}).then((options) => { // NOT OK + const formatted = prettier.format("bar", options); + }); +}); diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected index b1d940b437c..c0955082e00 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected @@ -187,6 +187,12 @@ nodes | tst3.js:5:9:5:9 | p | | tst3.js:6:12:6:12 | p | | tst3.js:6:12:6:12 | p | +| tst3.js:11:9:11:74 | code | +| tst3.js:11:16:11:74 | prettie ... bel" }) | +| tst3.js:11:32:11:39 | reg.body | +| tst3.js:11:32:11:39 | reg.body | +| tst3.js:12:12:12:15 | code | +| tst3.js:12:12:12:15 | code | edges | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | @@ -342,6 +348,11 @@ edges | tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p | | tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p | | tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p | +| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | +| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code | +| tst3.js:11:16:11:74 | prettie ... bel" }) | tst3.js:11:9:11:74 | code | +| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | +| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) | #select | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value | | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value | @@ -386,3 +397,4 @@ edges | tst2.js:36:12:36:12 | p | tst2.js:30:9:30:9 | p | tst2.js:36:12:36:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value | | tst2.js:37:12:37:18 | other.p | tst2.js:30:9:30:9 | p | tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value | | tst3.js:6:12:6:12 | p | tst3.js:5:9:5:9 | p | tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value | +| tst3.js:12:12:12:15 | code | tst3.js:11:32:11:39 | reg.body | tst3.js:12:12:12:15 | code | Cross-site scripting vulnerability due to $@. | tst3.js:11:32:11:39 | reg.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected index 6a919f7b43a..db284911aaf 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected @@ -40,3 +40,4 @@ | tst2.js:36:12:36:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value | | tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value | | tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value | +| tst3.js:12:12:12:15 | code | Cross-site scripting vulnerability due to $@. | tst3.js:11:32:11:39 | reg.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/tst3.js b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/tst3.js index 1fa1758c41c..c7d0fd91a4a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/tst3.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/tst3.js @@ -5,3 +5,9 @@ app.enable('x-powered-by').disable('x-powered-by').get('/', function (req, res) let { p } = req.params; res.send(p); // NOT OK }); + +const prettier = require("prettier"); +app.post("foobar", function (reg, res) { + const code = prettier.format(reg.body, { semi: false, parser: "babel" }); + res.send(code); // NOT OK +}); \ No newline at end of file From 27ff256b0e86c71f5a7f2483433029dfbb712945 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 15:34:01 +0200 Subject: [PATCH 089/272] add change note --- javascript/change-notes/2021-06-02-prettier.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/change-notes/2021-06-02-prettier.md diff --git a/javascript/change-notes/2021-06-02-prettier.md b/javascript/change-notes/2021-06-02-prettier.md new file mode 100644 index 00000000000..ce4277c5e33 --- /dev/null +++ b/javascript/change-notes/2021-06-02-prettier.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The dataflow libraries now model dataflow in the prettier library. + Affected packages are + [prettier](https://npmjs.com/package/prettier) From daf2cc3d53d61b933a96f4f89f41af0812e62a47 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Jun 2021 20:39:05 +0200 Subject: [PATCH 090/272] Java: Improve performance of `isUnreachableInCall()` --- .../semmle/code/java/dataflow/internal/DataFlowPrivate.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index e3ab07fce1f..c20fa87af6c 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -296,7 +296,9 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) { // which is used in a guard param.getAUse() = guard and // which controls `n` with the opposite value of `arg` - guard.controls(n.asExpr().getBasicBlock(), arg.getBooleanValue().booleanNot()) + guard + .controls(n.asExpr().getBasicBlock(), + pragma[only_bind_out](arg.getBooleanValue()).booleanNot()) ) } From 98ee763d576c24bcca83f5ea30115e9f4d68b41d Mon Sep 17 00:00:00 2001 From: AlonaHlobina <54394529+AlonaHlobina@users.noreply.github.com> Date: Wed, 2 Jun 2021 20:56:06 +0200 Subject: [PATCH 091/272] Update docs/codeql/support/reusables/versions-compilers.rst Co-authored-by: yo-h <55373593+yo-h@users.noreply.github.com> --- docs/codeql/support/reusables/versions-compilers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/support/reusables/versions-compilers.rst index 330922fd876..f983b5e0114 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/support/reusables/versions-compilers.rst @@ -17,7 +17,7 @@ .NET 5","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" Go (aka Golang), "Go up to 1.16", "Go 1.11 or more recent", ``.go`` - Java,"Java 7 to 15 [3]_, Java 16 (partially)","javac (OpenJDK and Oracle JDK), + Java,"Java 7 to 16 [3]_","javac (OpenJDK and Oracle JDK), Eclipse compiler for Java (ECJ) [4]_",``.java`` JavaScript,ECMAScript 2021 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhm``, ``.xhtml``, ``.vue``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [5]_" From 1e19da155c6a0785156d4fb4255979480000b570 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 21:25:48 +0200 Subject: [PATCH 092/272] move TaintedPath sink into TaintedPathCustomizations to avoid side-effects --- .../semmle/javascript/frameworks/Prettier.qll | 23 ------------------- .../dataflow/TaintedPathCustomizations.qll | 21 +++++++++++++++++ 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll b/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll index eeb8d1cdb87..81a1d596c14 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Prettier.qll @@ -26,27 +26,4 @@ private module Prettier { ) } } - - private import semmle.javascript.security.dataflow.TaintedPathCustomizations::TaintedPath as TaintedPath - - /** - * An argument given to the `prettier` library specificing the location of a config file. - */ - private class PrettierFileSink extends TaintedPath::Sink { - PrettierFileSink() { - this = - API::moduleImport("prettier") - .getMember(["resolveConfig", "resolveConfigFile", "getFileInfo"]) - .getACall() - .getArgument(0) - or - this = - API::moduleImport("prettier") - .getMember("resolveConfig") - .getACall() - .getParameter(1) - .getMember("config") - .getARhs() - } - } } diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index ebc877e0e25..d0814cd51d3 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -650,6 +650,27 @@ module TaintedPath { } } + /** + * An argument given to the `prettier` library specificing the location of a config file. + */ + private class PrettierFileSink extends TaintedPath::Sink { + PrettierFileSink() { + this = + API::moduleImport("prettier") + .getMember(["resolveConfig", "resolveConfigFile", "getFileInfo"]) + .getACall() + .getArgument(0) + or + this = + API::moduleImport("prettier") + .getMember("resolveConfig") + .getACall() + .getParameter(1) + .getMember("config") + .getARhs() + } + } + /** * Holds if there is a step `src -> dst` mapping `srclabel` to `dstlabel` relevant for path traversal vulnerabilities. */ From 69d6c74e7e8eb193f51fc7bb27a4b083b7da56fc Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 21:56:47 +0200 Subject: [PATCH 093/272] fix typescript version --- javascript/extractor/lib/typescript/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index 953f69edb1e..22b130f3bec 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "^4.3.2" + "typescript": "4.3.2" }, "scripts": { "build": "tsc --project tsconfig.json", From 431c9951319a254f9ead87d76c9997d9da7eb970 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 23:11:15 +0200 Subject: [PATCH 094/272] add support for the debug library --- javascript/change-notes/2021-06-02-debug.md | 4 ++++ .../semmle/javascript/frameworks/Logging.qll | 9 +++++++++ .../Security/CWE-312/CleartextLogging.expected | 18 ++++++++++++++++++ .../query-tests/Security/CWE-312/passwords.js | 8 +++++++- 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 javascript/change-notes/2021-06-02-debug.md diff --git a/javascript/change-notes/2021-06-02-debug.md b/javascript/change-notes/2021-06-02-debug.md new file mode 100644 index 00000000000..324ea96e2bf --- /dev/null +++ b/javascript/change-notes/2021-06-02-debug.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* Logging calls using the [debug](https://npmjs.com/package/immutable) library are now recognized. + Affected packages are + [debug](https://npmjs.com/package/debug) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Logging.qll b/javascript/ql/src/semmle/javascript/frameworks/Logging.qll index cf632cc6e1e..f6c02a54e8c 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Logging.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Logging.qll @@ -192,3 +192,12 @@ private module Fancylog { override DataFlow::Node getAMessageComponent() { result = getAnArgument() } } } + +/** + * A class modelling [debug](https://npmjs.org/package/debug) as a logging mechanism. + */ +private class DebugLoggerCall extends LoggerCall, API::CallNode { + DebugLoggerCall() { this = API::moduleImport("debug").getReturn().getACall() } + + override DataFlow::Node getAMessageComponent() { result = getAnArgument() } +} diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 85b1f872b52..6fc52f66868 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -125,6 +125,14 @@ nodes | passwords.js:164:14:164:21 | password | | passwords.js:164:14:164:42 | passwor ... g, "*") | | passwords.js:164:14:164:42 | passwor ... g, "*") | +| passwords.js:169:17:169:24 | password | +| passwords.js:169:17:169:24 | password | +| passwords.js:169:17:169:45 | passwor ... g, "*") | +| passwords.js:169:17:169:45 | passwor ... g, "*") | +| passwords.js:170:11:170:18 | password | +| passwords.js:170:11:170:18 | password | +| passwords.js:170:11:170:39 | passwor ... g, "*") | +| passwords.js:170:11:170:39 | passwor ... g, "*") | | passwords_in_browser1.js:2:13:2:20 | password | | passwords_in_browser1.js:2:13:2:20 | password | | passwords_in_browser1.js:2:13:2:20 | password | @@ -261,6 +269,14 @@ edges | passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | | passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | | passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | +| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | +| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | +| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | +| passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | +| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | +| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | +| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | +| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | | passwords_in_browser1.js:2:13:2:20 | password | passwords_in_browser1.js:2:13:2:20 | password | | passwords_in_browser2.js:2:13:2:20 | password | passwords_in_browser2.js:2:13:2:20 | password | | passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | @@ -304,6 +320,8 @@ edges | passwords.js:156:17:156:27 | process.env | passwords.js:156:17:156:27 | process.env | passwords.js:156:17:156:27 | process.env | Sensitive data returned by $@ is logged here. | passwords.js:156:17:156:27 | process.env | process environment | | passwords.js:163:14:163:41 | passwor ... g, "*") | passwords.js:163:14:163:21 | password | passwords.js:163:14:163:41 | passwor ... g, "*") | Sensitive data returned by $@ is logged here. | passwords.js:163:14:163:21 | password | an access to password | | passwords.js:164:14:164:42 | passwor ... g, "*") | passwords.js:164:14:164:21 | password | passwords.js:164:14:164:42 | passwor ... g, "*") | Sensitive data returned by $@ is logged here. | passwords.js:164:14:164:21 | password | an access to password | +| passwords.js:169:17:169:45 | passwor ... g, "*") | passwords.js:169:17:169:24 | password | passwords.js:169:17:169:45 | passwor ... g, "*") | Sensitive data returned by $@ is logged here. | passwords.js:169:17:169:24 | password | an access to password | +| passwords.js:170:11:170:39 | passwor ... g, "*") | passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | Sensitive data returned by $@ is logged here. | passwords.js:170:11:170:18 | password | an access to password | | passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_1.js:6:13:6:20 | password | an access to password | | passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_2.js:3:13:3:20 | password | an access to password | | passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_3.js:2:13:2:20 | password | an access to password | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js index 50dc80a65d0..3c9f7d32464 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js +++ b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js @@ -162,4 +162,10 @@ var Util = require('util'); console.log(password.replace(/./g, "*")); // OK! console.log(password.replace(/\./g, "*")); // NOT OK! console.log(password.replace(/foo/g, "*")); // NOT OK! -})(); \ No newline at end of file +})(); + +const debug = require('debug')('test'); +(function () { + console.log(password.replace(/foo/g, "*")); // NOT OK + debug(password.replace(/foo/g, "*")); // NOT OK +}); \ No newline at end of file From 185811ee227ad7f212b530fa8d29dac80e67ea6f Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 23:23:30 +0200 Subject: [PATCH 095/272] make MongooseFunction abstract --- javascript/ql/src/semmle/javascript/frameworks/NoSQL.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/src/semmle/javascript/frameworks/NoSQL.qll index f48dacea700..b27641e313b 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/NoSQL.qll @@ -166,7 +166,7 @@ private module Mongoose { /** * A Mongoose function. */ - private class MongooseFunction extends API::Node { + abstract private class MongooseFunction extends API::Node { /** * Gets the API-graph node for the result from this function (if the function returns a `Query`). */ From 48ab6305592dd9691e971f229caf4b31d17fccbc Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 23:43:40 +0200 Subject: [PATCH 096/272] model webpack-merge as an extend call --- .../ql/src/semmle/javascript/Extend.qll | 20 +++++++++++++++++++ .../library-tests/Extend/ExtendCalls.expected | 2 ++ .../ql/test/library-tests/Extend/tst.js | 5 +++++ 3 files changed, 27 insertions(+) diff --git a/javascript/ql/src/semmle/javascript/Extend.qll b/javascript/ql/src/semmle/javascript/Extend.qll index d50054fc4ee..d6c2087e39b 100644 --- a/javascript/ql/src/semmle/javascript/Extend.qll +++ b/javascript/ql/src/semmle/javascript/Extend.qll @@ -188,3 +188,23 @@ private class CloneStep extends PreCallGraphStep { ) } } + +/** + * A deep extend call from the [webpack-merge](https://npmjs.org/package/webpack-merge) library. + */ +private class WebpackMergeDeep extends ExtendCall, DataFlow::CallNode { + WebpackMergeDeep() { + this = DataFlow::moduleMember("webpack-merge", "merge").getACall() + or + this = + DataFlow::moduleMember("webpack-merge", ["mergeWithCustomize", "mergeWithRules"]) + .getACall() + .getACall() + } + + override DataFlow::Node getASourceOperand() { result = getAnArgument() } + + override DataFlow::Node getDestinationOperand() { none() } + + override predicate isDeep() { any() } +} diff --git a/javascript/ql/test/library-tests/Extend/ExtendCalls.expected b/javascript/ql/test/library-tests/Extend/ExtendCalls.expected index 89449bc4ff1..a4c66634f7c 100644 --- a/javascript/ql/test/library-tests/Extend/ExtendCalls.expected +++ b/javascript/ql/test/library-tests/Extend/ExtendCalls.expected @@ -41,3 +41,5 @@ | tst.js:79:1:79:45 | checkSh ... arg())) | OK | | tst.js:80:1:80:55 | checkSh ... arg())) | OK | | tst.js:81:1:81:51 | checkSh ... arg())) | OK | +| tst.js:85:1:85:44 | checkDe ... arg())) | OK | +| tst.js:86:1:86:61 | checkDe ... arg())) | OK | diff --git a/javascript/ql/test/library-tests/Extend/tst.js b/javascript/ql/test/library-tests/Extend/tst.js index 287fe57cdba..500178e3e5d 100644 --- a/javascript/ql/test/library-tests/Extend/tst.js +++ b/javascript/ql/test/library-tests/Extend/tst.js @@ -79,3 +79,8 @@ checkShallow(require('lodash').extend(base(), arg())); checkShallow(require("xtend")(base(), arg())); checkShallow(require("xtend/immutable")(base(), arg())); checkShallow(require("ramda").merge(base(), arg())); + +// webpack-merge. deep. +const webpackMerge = require('webpack-merge'); +checkDeep(webpackMerge.merge(base(), arg())); +checkDeep(webpackMerge.mergeWithCustomize({})(base(), arg())); From 143bf9de14730c032db33226bda612345054cd26 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 2 Jun 2021 23:48:29 +0200 Subject: [PATCH 097/272] add change note --- javascript/change-notes/2021-06-02-webpack-merge.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/change-notes/2021-06-02-webpack-merge.md diff --git a/javascript/change-notes/2021-06-02-webpack-merge.md b/javascript/change-notes/2021-06-02-webpack-merge.md new file mode 100644 index 00000000000..87ab83fffa6 --- /dev/null +++ b/javascript/change-notes/2021-06-02-webpack-merge.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The security queries recognize the merge call from [webpack-merge](https://npmjs.com/package/webpack-merge). + Affected packages are + [webpack-merge](https://npmjs.com/package/webpack-merge) From 3bda1f2e264c3d470339a78ac8d6b9ca08b70e9f Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 3 Jun 2021 00:43:41 +0200 Subject: [PATCH 098/272] update expected test output --- .../CallResolution/CallResolution.expected | 8 +- .../TypeScript/Types/printAst.expected | 561 +++++++++++++++++- 2 files changed, 539 insertions(+), 30 deletions(-) diff --git a/javascript/ql/test/library-tests/TypeScript/CallResolution/CallResolution.expected b/javascript/ql/test/library-tests/TypeScript/CallResolution/CallResolution.expected index 96b0086480e..a942a68076b 100644 --- a/javascript/ql/test/library-tests/TypeScript/CallResolution/CallResolution.expected +++ b/javascript/ql/test/library-tests/TypeScript/CallResolution/CallResolution.expected @@ -4,16 +4,16 @@ | tst.ts:55:3:55:27 | obj.ove ... od(num) | (x: number): number | 0 | | tst.ts:56:3:56:27 | obj.ove ... od(str) | (x: string): string | 1 | | tst.ts:57:3:57:26 | obj.ove ... hod([]) | (x: any): any | 2 | -| tst.ts:58:3:58:36 | obj.gen ... ([num]) | (x: number[]): T | 0 | -| tst.ts:59:3:59:39 | obj.gen ... : str}) | (x: Box): T | 1 | +| tst.ts:58:3:58:36 | obj.gen ... ([num]) | (x: number[]): number | 0 | +| tst.ts:59:3:59:39 | obj.gen ... : str}) | (x: Box): string | 1 | | tst.ts:60:3:60:34 | obj.gen ... od(num) | (x: any): any | 2 | | tst.ts:64:3:64:23 | obj.sim ... od(str) | (x: string): number | 0 | | tst.ts:65:3:65:24 | obj.gen ... od(str) | (x: string): string | 0 | | tst.ts:66:3:66:24 | obj.gen ... od(num) | (x: number): number | 0 | | tst.ts:67:3:67:27 | obj.ove ... od(num) | (x: number): number | 0 | | tst.ts:68:3:68:27 | obj.ove ... od(str) | (x: string): string | 1 | -| tst.ts:69:3:69:36 | obj.gen ... ([num]) | (x: number[]): T | 0 | -| tst.ts:70:3:70:39 | obj.gen ... : str}) | (x: Box): T | 1 | +| tst.ts:69:3:69:36 | obj.gen ... ([num]) | (x: number[]): number | 0 | +| tst.ts:70:3:70:39 | obj.gen ... : str}) | (x: Box): string | 1 | | tst.ts:74:3:74:28 | new Sim ... or(str) | new (x: string): SimpleConstructor | 0 | | tst.ts:75:3:75:29 | new Gen ... or(str) | new (x: string): GenericConstructor | 0 | | tst.ts:76:3:76:29 | new Gen ... or(num) | new (x: number): GenericConstructor | 0 | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected index 1f39b308479..d05b3228025 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected @@ -85,6 +85,12 @@ nodes | dummy.ts:4:20:4:20 | [RegExpNormalConstant] b | semmle.label | [RegExpNormalConstant] b | | dummy.ts:4:20:4:21 | [RegExpPlus] b+ | semmle.label | [RegExpPlus] b+ | | dummy.ts:4:22:4:22 | [RegExpNormalConstant] c | semmle.label | [RegExpNormalConstant] c | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | @@ -420,17 +426,182 @@ nodes | tst.ts:69:25:69:38 | [Label] yetAnotherType | semmle.label | [Label] yetAnotherType | | tst.ts:69:25:69:44 | [Property] yetAnotherType: true | semmle.label | [Property] yetAnotherType: true | | tst.ts:69:41:69:44 | [Literal] true | semmle.label | [Literal] true | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | semmle.label | [NamespaceDeclaration] module ... } } | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | semmle.order | 55 | +| tst.ts:71:8:71:11 | [VarDecl] TS43 | semmle.label | [VarDecl] TS43 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | +| tst.ts:73:13:73:18 | [Identifier] ThingI | semmle.label | [Identifier] ThingI | +| tst.ts:74:5:74:22 | [FunctionExpr] get size(): number | semmle.label | [FunctionExpr] get size(): number | +| tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | semmle.label | [GetterMethodSignature] get size(): number | +| tst.ts:74:9:74:12 | [Label] size | semmle.label | [Label] size | +| tst.ts:74:17:74:22 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:75:5:75:47 | [FunctionExpr] set siz ... olean); | semmle.label | [FunctionExpr] set siz ... olean); | +| tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | semmle.label | [SetterMethodSignature] set siz ... olean); | +| tst.ts:75:9:75:12 | [Label] size | semmle.label | [Label] size | +| tst.ts:75:14:75:18 | [SimpleParameter] value | semmle.label | [SimpleParameter] value | +| tst.ts:75:21:75:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | semmle.label | [UnionTypeExpr] number ... boolean | +| tst.ts:75:30:75:35 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:75:39:75:45 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | +| tst.ts:78:3:88:3 | [ExportDeclaration] export ... } } | semmle.label | [ExportDeclaration] export ... } } | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | semmle.label | [ClassDefinition,TypeDefinition] class T ... } } | +| tst.ts:78:16:78:20 | [VarDecl] Thing | semmle.label | [VarDecl] Thing | +| tst.ts:78:33:78:38 | [LocalTypeAccess] ThingI | semmle.label | [LocalTypeAccess] ThingI | +| tst.ts:78:40:78:39 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:78:40:78:39 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:78:40:78:39 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:79:5:79:9 | [Label] #size | semmle.label | [Label] #size | +| tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | semmle.label | [FieldDeclaration] #size = 0; | +| tst.ts:79:13:79:13 | [Literal] 0 | semmle.label | [Literal] 0 | +| tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | semmle.label | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | +| tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | semmle.label | [FunctionExpr] get siz ... ; } | +| tst.ts:81:9:81:12 | [Label] size | semmle.label | [Label] size | +| tst.ts:81:17:81:22 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:81:24:83:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:82:7:82:24 | [ReturnStmt] return this.#size; | semmle.label | [ReturnStmt] return this.#size; | +| tst.ts:82:14:82:17 | [ThisExpr] this | semmle.label | [ThisExpr] this | +| tst.ts:82:14:82:23 | [DotExpr] this.#size | semmle.label | [DotExpr] this.#size | +| tst.ts:82:19:82:23 | [Label] #size | semmle.label | [Label] #size | +| tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | semmle.label | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | +| tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | semmle.label | [FunctionExpr] set siz ... ; } | +| tst.ts:85:9:85:12 | [Label] size | semmle.label | [Label] size | +| tst.ts:85:14:85:18 | [SimpleParameter] value | semmle.label | [SimpleParameter] value | +| tst.ts:85:21:85:26 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | semmle.label | [UnionTypeExpr] string ... boolean | +| tst.ts:85:30:85:35 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:85:39:85:45 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | +| tst.ts:85:48:87:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:86:7:86:10 | [ThisExpr] this | semmle.label | [ThisExpr] this | +| tst.ts:86:7:86:16 | [DotExpr] this.#size | semmle.label | [DotExpr] this.#size | +| tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | semmle.label | [AssignExpr] this.#s ... (value) | +| tst.ts:86:7:86:33 | [ExprStmt] this.#s ... value); | semmle.label | [ExprStmt] this.#s ... value); | +| tst.ts:86:12:86:16 | [Label] #size | semmle.label | [Label] #size | +| tst.ts:86:20:86:25 | [VarRef] Number | semmle.label | [VarRef] Number | +| tst.ts:86:20:86:32 | [CallExpr] Number(value) | semmle.label | [CallExpr] Number(value) | +| tst.ts:86:27:86:31 | [VarRef] value | semmle.label | [VarRef] value | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | semmle.label | [ClassDefinition,TypeDefinition] class S ... } } | +| tst.ts:91:9:91:13 | [VarDecl] Super | semmle.label | [VarDecl] Super | +| tst.ts:91:15:91:14 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:91:15:91:14 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:91:15:91:14 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:92:5:92:10 | [Label] random | semmle.label | [Label] random | +| tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | semmle.label | [ClassInitializedMember,MethodDefinition] random( ... ; } | +| tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | semmle.label | [FunctionExpr] random( ... ; } | +| tst.ts:92:15:92:20 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:92:22:94:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:93:7:93:15 | [ReturnStmt] return 4; | semmle.label | [ReturnStmt] return 4; | +| tst.ts:93:14:93:14 | [Literal] 4 | semmle.label | [Literal] 4 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | semmle.label | [ClassDefinition,TypeDefinition] class S ... } } | +| tst.ts:97:9:97:11 | [VarDecl] Sub | semmle.label | [VarDecl] Sub | +| tst.ts:97:21:97:25 | [VarRef] Super | semmle.label | [VarRef] Super | +| tst.ts:97:27:97:26 | [BlockStmt] { super(...args); } | semmle.label | [BlockStmt] { super(...args); } | +| tst.ts:97:27:97:26 | [CallExpr] super(...args) | semmle.label | [CallExpr] super(...args) | +| tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | semmle.label | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | +| tst.ts:97:27:97:26 | [ExprStmt] super(...args); | semmle.label | [ExprStmt] super(...args); | +| tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | semmle.label | [FunctionExpr] (...arg ... rgs); } | +| tst.ts:97:27:97:26 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:97:27:97:26 | [SimpleParameter] args | semmle.label | [SimpleParameter] args | +| tst.ts:97:27:97:26 | [SpreadElement] ...args | semmle.label | [SpreadElement] ...args | +| tst.ts:97:27:97:26 | [SuperExpr] super | semmle.label | [SuperExpr] super | +| tst.ts:97:27:97:26 | [VarRef] args | semmle.label | [VarRef] args | +| tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | semmle.label | [ClassInitializedMember,MethodDefinition] overrid ... ; } | +| tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | semmle.label | [FunctionExpr] overrid ... ; } | +| tst.ts:98:14:98:19 | [Label] random | semmle.label | [Label] random | +| tst.ts:98:24:98:29 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:98:31:100:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:99:7:99:33 | [ReturnStmt] return ... ) * 10; | semmle.label | [ReturnStmt] return ... ) * 10; | +| tst.ts:99:14:99:18 | [SuperExpr] super | semmle.label | [SuperExpr] super | +| tst.ts:99:14:99:25 | [DotExpr] super.random | semmle.label | [DotExpr] super.random | +| tst.ts:99:14:99:27 | [MethodCallExpr] super.random() | semmle.label | [MethodCallExpr] super.random() | +| tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | semmle.label | [BinaryExpr] super.random() * 10 | +| tst.ts:99:20:99:25 | [Label] random | semmle.label | [Label] random | +| tst.ts:99:31:99:32 | [Literal] 10 | semmle.label | [Literal] 10 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | semmle.label | [FunctionDeclStmt] functio ... }`; } | +| tst.ts:104:12:104:14 | [VarDecl] bar | semmle.label | [VarDecl] bar | +| tst.ts:104:16:104:16 | [SimpleParameter] s | semmle.label | [SimpleParameter] s | +| tst.ts:104:19:104:24 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | semmle.label | [TemplateLiteralTypeExpr] `hello ${string}` | +| tst.ts:104:29:104:34 | [LiteralTypeExpr] hello | semmle.label | [LiteralTypeExpr] hello | +| tst.ts:104:37:104:42 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:104:46:107:3 | [BlockStmt] { / ... }`; } | semmle.label | [BlockStmt] { / ... }`; } | +| tst.ts:106:5:106:24 | [ReturnStmt] return `hello ${s}`; | semmle.label | [ReturnStmt] return `hello ${s}`; | +| tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | semmle.label | [TemplateLiteral] `hello ${s}` | +| tst.ts:106:13:106:18 | [TemplateElement] hello | semmle.label | [TemplateElement] hello | +| tst.ts:106:21:106:21 | [VarRef] s | semmle.label | [VarRef] s | +| tst.ts:109:3:109:50 | [DeclStmt] let s1 = ... | semmle.label | [DeclStmt] let s1 = ... | +| tst.ts:109:15:109:16 | [VarDecl] s1 | semmle.label | [VarDecl] s1 | +| tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | semmle.label | [VariableDeclarator] s1: `${ ... umber}` | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | semmle.label | [TemplateLiteralTypeExpr] `${numb ... umber}` | +| tst.ts:109:22:109:27 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:109:29:109:29 | [LiteralTypeExpr] - | semmle.label | [LiteralTypeExpr] - | +| tst.ts:109:32:109:37 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:109:39:109:39 | [LiteralTypeExpr] - | semmle.label | [LiteralTypeExpr] - | +| tst.ts:109:42:109:47 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:110:3:110:26 | [DeclStmt] let s2 = ... | semmle.label | [DeclStmt] let s2 = ... | +| tst.ts:110:15:110:16 | [VarDecl] s2 | semmle.label | [VarDecl] s2 | +| tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | semmle.label | [VariableDeclarator] s2: `1-2-3` | +| tst.ts:110:19:110:25 | [LiteralTypeExpr] `1-2-3` | semmle.label | [LiteralTypeExpr] `1-2-3` | +| tst.ts:110:19:110:25 | [TemplateLiteralTypeExpr] `1-2-3` | semmle.label | [TemplateLiteralTypeExpr] `1-2-3` | +| tst.ts:111:3:111:34 | [DeclStmt] let s3 = ... | semmle.label | [DeclStmt] let s3 = ... | +| tst.ts:111:15:111:16 | [VarDecl] s3 | semmle.label | [VarDecl] s3 | +| tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | semmle.label | [VariableDeclarator] s3: `${number}-2-3` | +| tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | semmle.label | [TemplateLiteralTypeExpr] `${number}-2-3` | +| tst.ts:111:22:111:27 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:111:29:111:32 | [LiteralTypeExpr] -2-3 | semmle.label | [LiteralTypeExpr] -2-3 | +| tst.ts:112:3:112:4 | [VarRef] s1 | semmle.label | [VarRef] s1 | +| tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | semmle.label | [AssignExpr] s1 = s2 | +| tst.ts:112:3:112:10 | [ExprStmt] s1 = s2; | semmle.label | [ExprStmt] s1 = s2; | +| tst.ts:112:8:112:9 | [VarRef] s2 | semmle.label | [VarRef] s2 | +| tst.ts:113:3:113:4 | [VarRef] s1 | semmle.label | [VarRef] s1 | +| tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | semmle.label | [AssignExpr] s1 = s3 | +| tst.ts:113:3:113:10 | [ExprStmt] s1 = s3; | semmle.label | [ExprStmt] s1 = s3; | +| tst.ts:113:8:113:9 | [VarRef] s3 | semmle.label | [VarRef] s3 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | semmle.label | [ClassDefinition,TypeDefinition] class F ... } } | +| tst.ts:116:9:116:11 | [VarDecl] Foo | semmle.label | [VarDecl] Foo | +| tst.ts:116:13:116:12 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:116:13:116:12 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:116:13:116:12 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:117:5:117:15 | [Label] #someMethod | semmle.label | [Label] #someMethod | +| tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | semmle.label | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | +| tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | semmle.label | [FunctionExpr] #someMe ... ; } | +| tst.ts:117:20:117:25 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:117:27:119:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:118:7:118:16 | [ReturnStmt] return 42; | semmle.label | [ReturnStmt] return 42; | +| tst.ts:118:14:118:15 | [Literal] 42 | semmle.label | [Literal] 42 | +| tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | semmle.label | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | +| tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | semmle.label | [FunctionExpr] get #so ... ; } | +| tst.ts:121:9:121:18 | [Label] #someValue | semmle.label | [Label] #someValue | +| tst.ts:121:23:121:28 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:121:30:123:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:122:7:122:17 | [ReturnStmt] return 100; | semmle.label | [ReturnStmt] return 100; | +| tst.ts:122:14:122:16 | [Literal] 100 | semmle.label | [Literal] 100 | +| tst.ts:125:5:125:16 | [Label] publicMethod | semmle.label | [Label] publicMethod | +| tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | semmle.label | [ClassInitializedMember,MethodDefinition] publicM ... ; } | +| tst.ts:125:5:128:5 | [FunctionExpr] publicM ... ; } | semmle.label | [FunctionExpr] publicM ... ; } | +| tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:126:7:126:10 | [ThisExpr] this | semmle.label | [ThisExpr] this | +| tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | semmle.label | [DotExpr] this.#someMethod | +| tst.ts:126:7:126:24 | [MethodCallExpr] this.#someMethod() | semmle.label | [MethodCallExpr] this.#someMethod() | +| tst.ts:126:7:126:25 | [ExprStmt] this.#someMethod(); | semmle.label | [ExprStmt] this.#someMethod(); | +| tst.ts:126:12:126:22 | [Label] #someMethod | semmle.label | [Label] #someMethod | +| tst.ts:127:7:127:29 | [ReturnStmt] return ... eValue; | semmle.label | [ReturnStmt] return ... eValue; | +| tst.ts:127:14:127:17 | [ThisExpr] this | semmle.label | [ThisExpr] this | +| tst.ts:127:14:127:28 | [DotExpr] this.#someValue | semmle.label | [DotExpr] this.#someValue | +| tst.ts:127:19:127:28 | [Label] #someValue | semmle.label | [Label] #someValue | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | -| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 55 | +| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 56 | | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B | | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | | type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... | -| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 56 | +| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 57 | | type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b | | type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B | | type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B | | type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | -| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 57 | +| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 58 | | type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray | | type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T | | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T | @@ -442,14 +613,14 @@ nodes | type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... | -| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 58 | +| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 59 | | type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> | | type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray | | type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | -| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 59 | +| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 60 | | type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json | | type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] | | type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -465,12 +636,12 @@ nodes | type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] | | type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... | -| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 60 | +| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 61 | | type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json | | type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json | | type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | -| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 61 | +| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 62 | | type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode | | type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] | | type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -486,7 +657,7 @@ nodes | type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | | type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] | | type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... | -| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 62 | +| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 63 | | type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode | | type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] | | type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | @@ -511,12 +682,12 @@ nodes | type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" | | type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" | | type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 63 | +| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 64 | | type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} | -| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 64 | +| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 65 | | type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} | | type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | @@ -524,36 +695,36 @@ nodes | type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | | type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor | | type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... | -| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 65 | +| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 66 | | type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj | | type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C | | type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C | | type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} | -| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 66 | +| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 67 | | type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} | | type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E | | type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... | -| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 67 | +| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 68 | | type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj | | type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E | | type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E | | type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} | -| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 68 | +| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 69 | | type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} | | type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N | | type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; | | type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... | -| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 69 | +| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 70 | | type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj | | type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N | | type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N | | type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 70 | +| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 71 | | type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | -| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 71 | +| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 72 | | type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I | | type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S | | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S | @@ -561,14 +732,14 @@ nodes | type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; | | type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S | | type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... | -| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 72 | +| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 73 | | type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i | | type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I | semmle.label | [VariableDeclarator] i: I | | type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I | | type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I | semmle.label | [GenericTypeExpr] I | | type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } | -| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 73 | +| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 74 | | type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | | type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | @@ -580,14 +751,14 @@ nodes | type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T | | type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... | -| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 74 | +| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 75 | | type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C | semmle.label | [VariableDeclarator] c: C | | type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C | | type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C | semmle.label | [GenericTypeExpr] C | | type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } | -| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 75 | +| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 76 | | type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color | | type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red | | type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red | @@ -596,29 +767,29 @@ nodes | type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue | | type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue | | type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... | -| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 76 | +| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 77 | | type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color | | type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color | | type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color | | type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } | -| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 77 | +| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 78 | | type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember | | type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member | | type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member | | type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... | -| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 78 | +| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 79 | | type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e | | type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember | | type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember | | type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | -| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 79 | +| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 80 | | type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias | | type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T | | type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T | | type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] | | type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... | -| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 80 | +| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 81 | | type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray | | type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> | | type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias | @@ -745,6 +916,10 @@ edges | dummy.ts:4:19:4:22 | [RegExpSequence] ab+c | dummy.ts:4:22:4:22 | [RegExpNormalConstant] c | semmle.order | 2 | | dummy.ts:4:20:4:21 | [RegExpPlus] b+ | dummy.ts:4:20:4:20 | [RegExpNormalConstant] b | semmle.label | 0 | | dummy.ts:4:20:4:21 | [RegExpPlus] b+ | dummy.ts:4:20:4:20 | [RegExpNormalConstant] b | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:86:27:86:31 | [VarRef] value | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:86:27:86:31 | [VarRef] value | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:97:27:97:26 | [SpreadElement] ...args | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:97:27:97:26 | [SpreadElement] ...args | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:28:14:28 | [SimpleParameter] y | semmle.label | 1 | @@ -761,6 +936,14 @@ edges | file://:0:0:0:0 | (Parameters) | tst.ts:20:23:20:23 | [SimpleParameter] x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:20:26:20:26 | [SimpleParameter] y | semmle.label | 1 | | file://:0:0:0:0 | (Parameters) | tst.ts:20:26:20:26 | [SimpleParameter] y | semmle.order | 1 | +| file://:0:0:0:0 | (Parameters) | tst.ts:75:14:75:18 | [SimpleParameter] value | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:75:14:75:18 | [SimpleParameter] value | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:85:14:85:18 | [SimpleParameter] value | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:85:14:85:18 | [SimpleParameter] value | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:97:27:97:26 | [SimpleParameter] args | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:97:27:97:26 | [SimpleParameter] args | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:104:16:104:16 | [SimpleParameter] s | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:104:16:104:16 | [SimpleParameter] s | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:21:19:21:21 | [SimpleParameter] key | semmle.label | 0 | @@ -1251,6 +1434,332 @@ edges | tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:25:69:38 | [Label] yetAnotherType | semmle.order | 1 | | tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:41:69:44 | [Literal] true | semmle.label | 2 | | tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:41:69:44 | [Literal] true | semmle.order | 2 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:71:8:71:11 | [VarDecl] TS43 | semmle.label | 1 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:71:8:71:11 | [VarDecl] TS43 | semmle.order | 1 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | semmle.label | 2 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | semmle.order | 2 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:78:3:88:3 | [ExportDeclaration] export ... } } | semmle.label | 3 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:78:3:88:3 | [ExportDeclaration] export ... } } | semmle.order | 3 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | semmle.label | 4 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | semmle.order | 4 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | semmle.label | 5 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | semmle.order | 5 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | semmle.label | 6 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | semmle.order | 6 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:109:3:109:50 | [DeclStmt] let s1 = ... | semmle.label | 7 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:109:3:109:50 | [DeclStmt] let s1 = ... | semmle.order | 7 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:110:3:110:26 | [DeclStmt] let s2 = ... | semmle.label | 8 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:110:3:110:26 | [DeclStmt] let s2 = ... | semmle.order | 8 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:111:3:111:34 | [DeclStmt] let s3 = ... | semmle.label | 9 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:111:3:111:34 | [DeclStmt] let s3 = ... | semmle.order | 9 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:112:3:112:10 | [ExprStmt] s1 = s2; | semmle.label | 10 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:112:3:112:10 | [ExprStmt] s1 = s2; | semmle.order | 10 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:113:3:113:10 | [ExprStmt] s1 = s3; | semmle.label | 11 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:113:3:113:10 | [ExprStmt] s1 = s3; | semmle.order | 11 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | semmle.label | 12 | +| tst.ts:71:1:130:1 | [NamespaceDeclaration] module ... } } | tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | semmle.order | 12 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | tst.ts:73:13:73:18 | [Identifier] ThingI | semmle.label | 1 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | tst.ts:73:13:73:18 | [Identifier] ThingI | semmle.order | 1 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | semmle.label | 2 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | semmle.order | 2 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | semmle.label | 3 | +| tst.ts:73:3:76:3 | [InterfaceDeclaration,TypeDefinition] interfa ... n); } | tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | semmle.order | 3 | +| tst.ts:74:5:74:22 | [FunctionExpr] get size(): number | tst.ts:74:17:74:22 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:74:5:74:22 | [FunctionExpr] get size(): number | tst.ts:74:17:74:22 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | tst.ts:74:5:74:22 | [FunctionExpr] get size(): number | semmle.label | 1 | +| tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | tst.ts:74:5:74:22 | [FunctionExpr] get size(): number | semmle.order | 1 | +| tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | tst.ts:74:9:74:12 | [Label] size | semmle.label | 2 | +| tst.ts:74:5:74:22 | [GetterMethodSignature] get size(): number | tst.ts:74:9:74:12 | [Label] size | semmle.order | 2 | +| tst.ts:75:5:75:47 | [FunctionExpr] set siz ... olean); | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:75:5:75:47 | [FunctionExpr] set siz ... olean); | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | tst.ts:75:5:75:47 | [FunctionExpr] set siz ... olean); | semmle.label | 1 | +| tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | tst.ts:75:5:75:47 | [FunctionExpr] set siz ... olean); | semmle.order | 1 | +| tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | tst.ts:75:9:75:12 | [Label] size | semmle.label | 2 | +| tst.ts:75:5:75:47 | [SetterMethodSignature] set siz ... olean); | tst.ts:75:9:75:12 | [Label] size | semmle.order | 2 | +| tst.ts:75:14:75:18 | [SimpleParameter] value | tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | semmle.label | 0 | +| tst.ts:75:14:75:18 | [SimpleParameter] value | tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | semmle.order | 0 | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | tst.ts:75:21:75:26 | [KeywordTypeExpr] number | semmle.label | 1 | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | tst.ts:75:21:75:26 | [KeywordTypeExpr] number | semmle.order | 1 | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | tst.ts:75:30:75:35 | [KeywordTypeExpr] string | semmle.label | 2 | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | tst.ts:75:30:75:35 | [KeywordTypeExpr] string | semmle.order | 2 | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | tst.ts:75:39:75:45 | [KeywordTypeExpr] boolean | semmle.label | 3 | +| tst.ts:75:21:75:45 | [UnionTypeExpr] number ... boolean | tst.ts:75:39:75:45 | [KeywordTypeExpr] boolean | semmle.order | 3 | +| tst.ts:78:3:88:3 | [ExportDeclaration] export ... } } | tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | semmle.label | 1 | +| tst.ts:78:3:88:3 | [ExportDeclaration] export ... } } | tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | semmle.order | 1 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:78:16:78:20 | [VarDecl] Thing | semmle.label | 1 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:78:16:78:20 | [VarDecl] Thing | semmle.order | 1 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:78:33:78:38 | [LocalTypeAccess] ThingI | semmle.label | 2 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:78:33:78:38 | [LocalTypeAccess] ThingI | semmle.order | 2 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 3 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 3 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | semmle.label | 4 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | semmle.order | 4 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | semmle.label | 5 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | semmle.order | 5 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | semmle.label | 6 | +| tst.ts:78:10:88:3 | [ClassDefinition,TypeDefinition] class T ... } } | tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | semmle.order | 6 | +| tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:78:40:78:39 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:78:40:78:39 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:78:40:78:39 | [Label] constructor | semmle.label | 1 | +| tst.ts:78:40:78:39 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:78:40:78:39 | [Label] constructor | semmle.order | 1 | +| tst.ts:78:40:78:39 | [FunctionExpr] () {} | tst.ts:78:40:78:39 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:78:40:78:39 | [FunctionExpr] () {} | tst.ts:78:40:78:39 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | tst.ts:79:5:79:9 | [Label] #size | semmle.label | 1 | +| tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | tst.ts:79:5:79:9 | [Label] #size | semmle.order | 1 | +| tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | tst.ts:79:13:79:13 | [Literal] 0 | semmle.label | 2 | +| tst.ts:79:5:79:14 | [FieldDeclaration] #size = 0; | tst.ts:79:13:79:13 | [Literal] 0 | semmle.order | 2 | +| tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | semmle.label | 1 | +| tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | semmle.order | 1 | +| tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | tst.ts:81:9:81:12 | [Label] size | semmle.label | 2 | +| tst.ts:81:5:83:5 | [ClassInitializedMember,GetterMethodDefinition] get siz ... ; } | tst.ts:81:9:81:12 | [Label] size | semmle.order | 2 | +| tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | tst.ts:81:17:81:22 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | tst.ts:81:17:81:22 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | tst.ts:81:24:83:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:81:5:83:5 | [FunctionExpr] get siz ... ; } | tst.ts:81:24:83:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:81:24:83:5 | [BlockStmt] { ... ; } | tst.ts:82:7:82:24 | [ReturnStmt] return this.#size; | semmle.label | 1 | +| tst.ts:81:24:83:5 | [BlockStmt] { ... ; } | tst.ts:82:7:82:24 | [ReturnStmt] return this.#size; | semmle.order | 1 | +| tst.ts:82:7:82:24 | [ReturnStmt] return this.#size; | tst.ts:82:14:82:23 | [DotExpr] this.#size | semmle.label | 1 | +| tst.ts:82:7:82:24 | [ReturnStmt] return this.#size; | tst.ts:82:14:82:23 | [DotExpr] this.#size | semmle.order | 1 | +| tst.ts:82:14:82:23 | [DotExpr] this.#size | tst.ts:82:14:82:17 | [ThisExpr] this | semmle.label | 1 | +| tst.ts:82:14:82:23 | [DotExpr] this.#size | tst.ts:82:14:82:17 | [ThisExpr] this | semmle.order | 1 | +| tst.ts:82:14:82:23 | [DotExpr] this.#size | tst.ts:82:19:82:23 | [Label] #size | semmle.label | 2 | +| tst.ts:82:14:82:23 | [DotExpr] this.#size | tst.ts:82:19:82:23 | [Label] #size | semmle.order | 2 | +| tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | semmle.label | 1 | +| tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | semmle.order | 1 | +| tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | tst.ts:85:9:85:12 | [Label] size | semmle.label | 2 | +| tst.ts:85:5:87:5 | [ClassInitializedMember,SetterMethodDefinition] set siz ... ; } | tst.ts:85:9:85:12 | [Label] size | semmle.order | 2 | +| tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | tst.ts:85:48:87:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:85:5:87:5 | [FunctionExpr] set siz ... ; } | tst.ts:85:48:87:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:85:14:85:18 | [SimpleParameter] value | tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | semmle.label | 0 | +| tst.ts:85:14:85:18 | [SimpleParameter] value | tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | semmle.order | 0 | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | tst.ts:85:21:85:26 | [KeywordTypeExpr] string | semmle.label | 1 | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | tst.ts:85:21:85:26 | [KeywordTypeExpr] string | semmle.order | 1 | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | tst.ts:85:30:85:35 | [KeywordTypeExpr] number | semmle.label | 2 | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | tst.ts:85:30:85:35 | [KeywordTypeExpr] number | semmle.order | 2 | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | tst.ts:85:39:85:45 | [KeywordTypeExpr] boolean | semmle.label | 3 | +| tst.ts:85:21:85:45 | [UnionTypeExpr] string ... boolean | tst.ts:85:39:85:45 | [KeywordTypeExpr] boolean | semmle.order | 3 | +| tst.ts:85:48:87:5 | [BlockStmt] { ... ; } | tst.ts:86:7:86:33 | [ExprStmt] this.#s ... value); | semmle.label | 1 | +| tst.ts:85:48:87:5 | [BlockStmt] { ... ; } | tst.ts:86:7:86:33 | [ExprStmt] this.#s ... value); | semmle.order | 1 | +| tst.ts:86:7:86:16 | [DotExpr] this.#size | tst.ts:86:7:86:10 | [ThisExpr] this | semmle.label | 1 | +| tst.ts:86:7:86:16 | [DotExpr] this.#size | tst.ts:86:7:86:10 | [ThisExpr] this | semmle.order | 1 | +| tst.ts:86:7:86:16 | [DotExpr] this.#size | tst.ts:86:12:86:16 | [Label] #size | semmle.label | 2 | +| tst.ts:86:7:86:16 | [DotExpr] this.#size | tst.ts:86:12:86:16 | [Label] #size | semmle.order | 2 | +| tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | tst.ts:86:7:86:16 | [DotExpr] this.#size | semmle.label | 1 | +| tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | tst.ts:86:7:86:16 | [DotExpr] this.#size | semmle.order | 1 | +| tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | tst.ts:86:20:86:32 | [CallExpr] Number(value) | semmle.label | 2 | +| tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | tst.ts:86:20:86:32 | [CallExpr] Number(value) | semmle.order | 2 | +| tst.ts:86:7:86:33 | [ExprStmt] this.#s ... value); | tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | semmle.label | 1 | +| tst.ts:86:7:86:33 | [ExprStmt] this.#s ... value); | tst.ts:86:7:86:32 | [AssignExpr] this.#s ... (value) | semmle.order | 1 | +| tst.ts:86:20:86:32 | [CallExpr] Number(value) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.ts:86:20:86:32 | [CallExpr] Number(value) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.ts:86:20:86:32 | [CallExpr] Number(value) | tst.ts:86:20:86:25 | [VarRef] Number | semmle.label | 0 | +| tst.ts:86:20:86:32 | [CallExpr] Number(value) | tst.ts:86:20:86:25 | [VarRef] Number | semmle.order | 0 | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:91:9:91:13 | [VarDecl] Super | semmle.label | 1 | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:91:9:91:13 | [VarDecl] Super | semmle.order | 1 | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | semmle.label | 3 | +| tst.ts:91:3:95:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | semmle.order | 3 | +| tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:91:15:91:14 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:91:15:91:14 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:91:15:91:14 | [Label] constructor | semmle.label | 1 | +| tst.ts:91:15:91:14 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:91:15:91:14 | [Label] constructor | semmle.order | 1 | +| tst.ts:91:15:91:14 | [FunctionExpr] () {} | tst.ts:91:15:91:14 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:91:15:91:14 | [FunctionExpr] () {} | tst.ts:91:15:91:14 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | tst.ts:92:5:92:10 | [Label] random | semmle.label | 1 | +| tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | tst.ts:92:5:92:10 | [Label] random | semmle.order | 1 | +| tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | semmle.label | 2 | +| tst.ts:92:5:94:5 | [ClassInitializedMember,MethodDefinition] random( ... ; } | tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | semmle.order | 2 | +| tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | tst.ts:92:15:92:20 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | tst.ts:92:15:92:20 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | tst.ts:92:22:94:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:92:5:94:5 | [FunctionExpr] random( ... ; } | tst.ts:92:22:94:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:92:22:94:5 | [BlockStmt] { ... ; } | tst.ts:93:7:93:15 | [ReturnStmt] return 4; | semmle.label | 1 | +| tst.ts:92:22:94:5 | [BlockStmt] { ... ; } | tst.ts:93:7:93:15 | [ReturnStmt] return 4; | semmle.order | 1 | +| tst.ts:93:7:93:15 | [ReturnStmt] return 4; | tst.ts:93:14:93:14 | [Literal] 4 | semmle.label | 1 | +| tst.ts:93:7:93:15 | [ReturnStmt] return 4; | tst.ts:93:14:93:14 | [Literal] 4 | semmle.order | 1 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:97:9:97:11 | [VarDecl] Sub | semmle.label | 1 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:97:9:97:11 | [VarDecl] Sub | semmle.order | 1 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:97:21:97:25 | [VarRef] Super | semmle.label | 2 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:97:21:97:25 | [VarRef] Super | semmle.order | 2 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | semmle.label | 3 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | semmle.order | 3 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | semmle.label | 4 | +| tst.ts:97:3:101:3 | [ClassDefinition,TypeDefinition] class S ... } } | tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | semmle.order | 4 | +| tst.ts:97:27:97:26 | [BlockStmt] { super(...args); } | tst.ts:97:27:97:26 | [ExprStmt] super(...args); | semmle.label | 1 | +| tst.ts:97:27:97:26 | [BlockStmt] { super(...args); } | tst.ts:97:27:97:26 | [ExprStmt] super(...args); | semmle.order | 1 | +| tst.ts:97:27:97:26 | [CallExpr] super(...args) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.ts:97:27:97:26 | [CallExpr] super(...args) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.ts:97:27:97:26 | [CallExpr] super(...args) | tst.ts:97:27:97:26 | [SuperExpr] super | semmle.label | 0 | +| tst.ts:97:27:97:26 | [CallExpr] super(...args) | tst.ts:97:27:97:26 | [SuperExpr] super | semmle.order | 0 | +| tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | semmle.label | 2 | +| tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | semmle.order | 2 | +| tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | tst.ts:97:27:97:26 | [Label] constructor | semmle.label | 1 | +| tst.ts:97:27:97:26 | [ClassInitializedMember,ConstructorDefinition] constru ... rgs); } | tst.ts:97:27:97:26 | [Label] constructor | semmle.order | 1 | +| tst.ts:97:27:97:26 | [ExprStmt] super(...args); | tst.ts:97:27:97:26 | [CallExpr] super(...args) | semmle.label | 1 | +| tst.ts:97:27:97:26 | [ExprStmt] super(...args); | tst.ts:97:27:97:26 | [CallExpr] super(...args) | semmle.order | 1 | +| tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | tst.ts:97:27:97:26 | [BlockStmt] { super(...args); } | semmle.label | 5 | +| tst.ts:97:27:97:26 | [FunctionExpr] (...arg ... rgs); } | tst.ts:97:27:97:26 | [BlockStmt] { super(...args); } | semmle.order | 5 | +| tst.ts:97:27:97:26 | [SpreadElement] ...args | tst.ts:97:27:97:26 | [VarRef] args | semmle.label | 1 | +| tst.ts:97:27:97:26 | [SpreadElement] ...args | tst.ts:97:27:97:26 | [VarRef] args | semmle.order | 1 | +| tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | semmle.label | 1 | +| tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | semmle.order | 1 | +| tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | tst.ts:98:14:98:19 | [Label] random | semmle.label | 2 | +| tst.ts:98:5:100:5 | [ClassInitializedMember,MethodDefinition] overrid ... ; } | tst.ts:98:14:98:19 | [Label] random | semmle.order | 2 | +| tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | tst.ts:98:24:98:29 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | tst.ts:98:24:98:29 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | tst.ts:98:31:100:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:98:5:100:5 | [FunctionExpr] overrid ... ; } | tst.ts:98:31:100:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:98:31:100:5 | [BlockStmt] { ... ; } | tst.ts:99:7:99:33 | [ReturnStmt] return ... ) * 10; | semmle.label | 1 | +| tst.ts:98:31:100:5 | [BlockStmt] { ... ; } | tst.ts:99:7:99:33 | [ReturnStmt] return ... ) * 10; | semmle.order | 1 | +| tst.ts:99:7:99:33 | [ReturnStmt] return ... ) * 10; | tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | semmle.label | 1 | +| tst.ts:99:7:99:33 | [ReturnStmt] return ... ) * 10; | tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | semmle.order | 1 | +| tst.ts:99:14:99:25 | [DotExpr] super.random | tst.ts:99:14:99:18 | [SuperExpr] super | semmle.label | 1 | +| tst.ts:99:14:99:25 | [DotExpr] super.random | tst.ts:99:14:99:18 | [SuperExpr] super | semmle.order | 1 | +| tst.ts:99:14:99:25 | [DotExpr] super.random | tst.ts:99:20:99:25 | [Label] random | semmle.label | 2 | +| tst.ts:99:14:99:25 | [DotExpr] super.random | tst.ts:99:20:99:25 | [Label] random | semmle.order | 2 | +| tst.ts:99:14:99:27 | [MethodCallExpr] super.random() | tst.ts:99:14:99:25 | [DotExpr] super.random | semmle.label | 0 | +| tst.ts:99:14:99:27 | [MethodCallExpr] super.random() | tst.ts:99:14:99:25 | [DotExpr] super.random | semmle.order | 0 | +| tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | tst.ts:99:14:99:27 | [MethodCallExpr] super.random() | semmle.label | 1 | +| tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | tst.ts:99:14:99:27 | [MethodCallExpr] super.random() | semmle.order | 1 | +| tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | tst.ts:99:31:99:32 | [Literal] 10 | semmle.label | 2 | +| tst.ts:99:14:99:32 | [BinaryExpr] super.random() * 10 | tst.ts:99:31:99:32 | [Literal] 10 | semmle.order | 2 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | tst.ts:104:12:104:14 | [VarDecl] bar | semmle.label | 0 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | tst.ts:104:12:104:14 | [VarDecl] bar | semmle.order | 0 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | semmle.label | 4 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | semmle.order | 4 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | tst.ts:104:46:107:3 | [BlockStmt] { / ... }`; } | semmle.label | 5 | +| tst.ts:104:3:107:3 | [FunctionDeclStmt] functio ... }`; } | tst.ts:104:46:107:3 | [BlockStmt] { / ... }`; } | semmle.order | 5 | +| tst.ts:104:16:104:16 | [SimpleParameter] s | tst.ts:104:19:104:24 | [KeywordTypeExpr] string | semmle.label | 0 | +| tst.ts:104:16:104:16 | [SimpleParameter] s | tst.ts:104:19:104:24 | [KeywordTypeExpr] string | semmle.order | 0 | +| tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | tst.ts:104:29:104:34 | [LiteralTypeExpr] hello | semmle.label | 1 | +| tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | tst.ts:104:29:104:34 | [LiteralTypeExpr] hello | semmle.order | 1 | +| tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | tst.ts:104:37:104:42 | [KeywordTypeExpr] string | semmle.label | 2 | +| tst.ts:104:28:104:44 | [TemplateLiteralTypeExpr] `hello ${string}` | tst.ts:104:37:104:42 | [KeywordTypeExpr] string | semmle.order | 2 | +| tst.ts:104:46:107:3 | [BlockStmt] { / ... }`; } | tst.ts:106:5:106:24 | [ReturnStmt] return `hello ${s}`; | semmle.label | 1 | +| tst.ts:104:46:107:3 | [BlockStmt] { / ... }`; } | tst.ts:106:5:106:24 | [ReturnStmt] return `hello ${s}`; | semmle.order | 1 | +| tst.ts:106:5:106:24 | [ReturnStmt] return `hello ${s}`; | tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | semmle.label | 1 | +| tst.ts:106:5:106:24 | [ReturnStmt] return `hello ${s}`; | tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | semmle.order | 1 | +| tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | tst.ts:106:13:106:18 | [TemplateElement] hello | semmle.label | 1 | +| tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | tst.ts:106:13:106:18 | [TemplateElement] hello | semmle.order | 1 | +| tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | tst.ts:106:21:106:21 | [VarRef] s | semmle.label | 2 | +| tst.ts:106:12:106:23 | [TemplateLiteral] `hello ${s}` | tst.ts:106:21:106:21 | [VarRef] s | semmle.order | 2 | +| tst.ts:109:3:109:50 | [DeclStmt] let s1 = ... | tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | semmle.label | 1 | +| tst.ts:109:3:109:50 | [DeclStmt] let s1 = ... | tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | semmle.order | 1 | +| tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | tst.ts:109:15:109:16 | [VarDecl] s1 | semmle.label | 1 | +| tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | tst.ts:109:15:109:16 | [VarDecl] s1 | semmle.order | 1 | +| tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | semmle.label | 2 | +| tst.ts:109:15:109:49 | [VariableDeclarator] s1: `${ ... umber}` | tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | semmle.order | 2 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:22:109:27 | [KeywordTypeExpr] number | semmle.label | 1 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:22:109:27 | [KeywordTypeExpr] number | semmle.order | 1 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:29:109:29 | [LiteralTypeExpr] - | semmle.label | 2 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:29:109:29 | [LiteralTypeExpr] - | semmle.order | 2 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:32:109:37 | [KeywordTypeExpr] number | semmle.label | 3 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:32:109:37 | [KeywordTypeExpr] number | semmle.order | 3 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:39:109:39 | [LiteralTypeExpr] - | semmle.label | 4 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:39:109:39 | [LiteralTypeExpr] - | semmle.order | 4 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:42:109:47 | [KeywordTypeExpr] number | semmle.label | 5 | +| tst.ts:109:19:109:49 | [TemplateLiteralTypeExpr] `${numb ... umber}` | tst.ts:109:42:109:47 | [KeywordTypeExpr] number | semmle.order | 5 | +| tst.ts:110:3:110:26 | [DeclStmt] let s2 = ... | tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | semmle.label | 1 | +| tst.ts:110:3:110:26 | [DeclStmt] let s2 = ... | tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | semmle.order | 1 | +| tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | tst.ts:110:15:110:16 | [VarDecl] s2 | semmle.label | 1 | +| tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | tst.ts:110:15:110:16 | [VarDecl] s2 | semmle.order | 1 | +| tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | tst.ts:110:19:110:25 | [TemplateLiteralTypeExpr] `1-2-3` | semmle.label | 2 | +| tst.ts:110:15:110:25 | [VariableDeclarator] s2: `1-2-3` | tst.ts:110:19:110:25 | [TemplateLiteralTypeExpr] `1-2-3` | semmle.order | 2 | +| tst.ts:110:19:110:25 | [TemplateLiteralTypeExpr] `1-2-3` | tst.ts:110:19:110:25 | [LiteralTypeExpr] `1-2-3` | semmle.label | 1 | +| tst.ts:110:19:110:25 | [TemplateLiteralTypeExpr] `1-2-3` | tst.ts:110:19:110:25 | [LiteralTypeExpr] `1-2-3` | semmle.order | 1 | +| tst.ts:111:3:111:34 | [DeclStmt] let s3 = ... | tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | semmle.label | 1 | +| tst.ts:111:3:111:34 | [DeclStmt] let s3 = ... | tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | semmle.order | 1 | +| tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | tst.ts:111:15:111:16 | [VarDecl] s3 | semmle.label | 1 | +| tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | tst.ts:111:15:111:16 | [VarDecl] s3 | semmle.order | 1 | +| tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | semmle.label | 2 | +| tst.ts:111:15:111:33 | [VariableDeclarator] s3: `${number}-2-3` | tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | semmle.order | 2 | +| tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | tst.ts:111:22:111:27 | [KeywordTypeExpr] number | semmle.label | 1 | +| tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | tst.ts:111:22:111:27 | [KeywordTypeExpr] number | semmle.order | 1 | +| tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | tst.ts:111:29:111:32 | [LiteralTypeExpr] -2-3 | semmle.label | 2 | +| tst.ts:111:19:111:33 | [TemplateLiteralTypeExpr] `${number}-2-3` | tst.ts:111:29:111:32 | [LiteralTypeExpr] -2-3 | semmle.order | 2 | +| tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | tst.ts:112:3:112:4 | [VarRef] s1 | semmle.label | 1 | +| tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | tst.ts:112:3:112:4 | [VarRef] s1 | semmle.order | 1 | +| tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | tst.ts:112:8:112:9 | [VarRef] s2 | semmle.label | 2 | +| tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | tst.ts:112:8:112:9 | [VarRef] s2 | semmle.order | 2 | +| tst.ts:112:3:112:10 | [ExprStmt] s1 = s2; | tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | semmle.label | 1 | +| tst.ts:112:3:112:10 | [ExprStmt] s1 = s2; | tst.ts:112:3:112:9 | [AssignExpr] s1 = s2 | semmle.order | 1 | +| tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | tst.ts:113:3:113:4 | [VarRef] s1 | semmle.label | 1 | +| tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | tst.ts:113:3:113:4 | [VarRef] s1 | semmle.order | 1 | +| tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | tst.ts:113:8:113:9 | [VarRef] s3 | semmle.label | 2 | +| tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | tst.ts:113:8:113:9 | [VarRef] s3 | semmle.order | 2 | +| tst.ts:113:3:113:10 | [ExprStmt] s1 = s3; | tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | semmle.label | 1 | +| tst.ts:113:3:113:10 | [ExprStmt] s1 = s3; | tst.ts:113:3:113:9 | [AssignExpr] s1 = s3 | semmle.order | 1 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:116:9:116:11 | [VarDecl] Foo | semmle.label | 1 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:116:9:116:11 | [VarDecl] Foo | semmle.order | 1 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | semmle.label | 3 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | semmle.order | 3 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | semmle.label | 4 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | semmle.order | 4 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | semmle.label | 5 | +| tst.ts:116:3:129:3 | [ClassDefinition,TypeDefinition] class F ... } } | tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | semmle.order | 5 | +| tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:116:13:116:12 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:116:13:116:12 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:116:13:116:12 | [Label] constructor | semmle.label | 1 | +| tst.ts:116:13:116:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:116:13:116:12 | [Label] constructor | semmle.order | 1 | +| tst.ts:116:13:116:12 | [FunctionExpr] () {} | tst.ts:116:13:116:12 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:116:13:116:12 | [FunctionExpr] () {} | tst.ts:116:13:116:12 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | tst.ts:117:5:117:15 | [Label] #someMethod | semmle.label | 1 | +| tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | tst.ts:117:5:117:15 | [Label] #someMethod | semmle.order | 1 | +| tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | semmle.label | 2 | +| tst.ts:117:5:119:5 | [ClassInitializedMember,MethodDefinition] #someMe ... ; } | tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | semmle.order | 2 | +| tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | tst.ts:117:20:117:25 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | tst.ts:117:20:117:25 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | tst.ts:117:27:119:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:117:5:119:5 | [FunctionExpr] #someMe ... ; } | tst.ts:117:27:119:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:117:27:119:5 | [BlockStmt] { ... ; } | tst.ts:118:7:118:16 | [ReturnStmt] return 42; | semmle.label | 1 | +| tst.ts:117:27:119:5 | [BlockStmt] { ... ; } | tst.ts:118:7:118:16 | [ReturnStmt] return 42; | semmle.order | 1 | +| tst.ts:118:7:118:16 | [ReturnStmt] return 42; | tst.ts:118:14:118:15 | [Literal] 42 | semmle.label | 1 | +| tst.ts:118:7:118:16 | [ReturnStmt] return 42; | tst.ts:118:14:118:15 | [Literal] 42 | semmle.order | 1 | +| tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | semmle.label | 1 | +| tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | semmle.order | 1 | +| tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | tst.ts:121:9:121:18 | [Label] #someValue | semmle.label | 2 | +| tst.ts:121:5:123:5 | [ClassInitializedMember,GetterMethodDefinition] get #so ... ; } | tst.ts:121:9:121:18 | [Label] #someValue | semmle.order | 2 | +| tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | tst.ts:121:23:121:28 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | tst.ts:121:23:121:28 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | tst.ts:121:30:123:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:121:5:123:5 | [FunctionExpr] get #so ... ; } | tst.ts:121:30:123:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:121:30:123:5 | [BlockStmt] { ... ; } | tst.ts:122:7:122:17 | [ReturnStmt] return 100; | semmle.label | 1 | +| tst.ts:121:30:123:5 | [BlockStmt] { ... ; } | tst.ts:122:7:122:17 | [ReturnStmt] return 100; | semmle.order | 1 | +| tst.ts:122:7:122:17 | [ReturnStmt] return 100; | tst.ts:122:14:122:16 | [Literal] 100 | semmle.label | 1 | +| tst.ts:122:7:122:17 | [ReturnStmt] return 100; | tst.ts:122:14:122:16 | [Literal] 100 | semmle.order | 1 | +| tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | tst.ts:125:5:125:16 | [Label] publicMethod | semmle.label | 1 | +| tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | tst.ts:125:5:125:16 | [Label] publicMethod | semmle.order | 1 | +| tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | tst.ts:125:5:128:5 | [FunctionExpr] publicM ... ; } | semmle.label | 2 | +| tst.ts:125:5:128:5 | [ClassInitializedMember,MethodDefinition] publicM ... ; } | tst.ts:125:5:128:5 | [FunctionExpr] publicM ... ; } | semmle.order | 2 | +| tst.ts:125:5:128:5 | [FunctionExpr] publicM ... ; } | tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:125:5:128:5 | [FunctionExpr] publicM ... ; } | tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | tst.ts:126:7:126:25 | [ExprStmt] this.#someMethod(); | semmle.label | 1 | +| tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | tst.ts:126:7:126:25 | [ExprStmt] this.#someMethod(); | semmle.order | 1 | +| tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | tst.ts:127:7:127:29 | [ReturnStmt] return ... eValue; | semmle.label | 2 | +| tst.ts:125:20:128:5 | [BlockStmt] { ... ; } | tst.ts:127:7:127:29 | [ReturnStmt] return ... eValue; | semmle.order | 2 | +| tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | tst.ts:126:7:126:10 | [ThisExpr] this | semmle.label | 1 | +| tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | tst.ts:126:7:126:10 | [ThisExpr] this | semmle.order | 1 | +| tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | tst.ts:126:12:126:22 | [Label] #someMethod | semmle.label | 2 | +| tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | tst.ts:126:12:126:22 | [Label] #someMethod | semmle.order | 2 | +| tst.ts:126:7:126:24 | [MethodCallExpr] this.#someMethod() | tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | semmle.label | 0 | +| tst.ts:126:7:126:24 | [MethodCallExpr] this.#someMethod() | tst.ts:126:7:126:22 | [DotExpr] this.#someMethod | semmle.order | 0 | +| tst.ts:126:7:126:25 | [ExprStmt] this.#someMethod(); | tst.ts:126:7:126:24 | [MethodCallExpr] this.#someMethod() | semmle.label | 1 | +| tst.ts:126:7:126:25 | [ExprStmt] this.#someMethod(); | tst.ts:126:7:126:24 | [MethodCallExpr] this.#someMethod() | semmle.order | 1 | +| tst.ts:127:7:127:29 | [ReturnStmt] return ... eValue; | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | semmle.label | 1 | +| tst.ts:127:7:127:29 | [ReturnStmt] return ... eValue; | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | semmle.order | 1 | +| tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:14:127:17 | [ThisExpr] this | semmle.label | 1 | +| tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:14:127:17 | [ThisExpr] this | semmle.order | 1 | +| tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:19:127:28 | [Label] #someValue | semmle.label | 2 | +| tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:19:127:28 | [Label] #someValue | semmle.order | 2 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | 1 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.order | 1 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | 2 | From 374adc88194f6e82ddd72fa3a021fc9342adc0e9 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 3 Jun 2021 08:17:17 +0200 Subject: [PATCH 099/272] Temporarily disable CSV coverage PR file comparison step --- .github/workflows/csv-coverage.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/csv-coverage.yml b/.github/workflows/csv-coverage.yml index 093d6ead060..54c172d66d3 100644 --- a/.github/workflows/csv-coverage.yml +++ b/.github/workflows/csv-coverage.yml @@ -70,8 +70,8 @@ jobs: with: name: rst-flow-model-coverage path: flow-model-coverage-*.rst - - name: Check coverage files - if: github.event.pull_request - run: | - python script/misc/scripts/library-coverage/compare-files.py codeqlModels + # - name: Check coverage files + # if: github.event.pull_request + # run: | + # python script/misc/scripts/library-coverage/compare-files.py codeqlModels From e86c534c48d6362be4d58a2e50cfa122f8315212 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 3 Jun 2021 09:02:49 +0200 Subject: [PATCH 100/272] Revert "Java: Update coverage." This reverts commit 1c081eeaedb27332623e67231bf21c1f5d8a62d5. --- .../library-coverage/flow-model-coverage.csv | 18 +++++++++--------- .../library-coverage/flow-model-coverage.rst | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/java/documentation/library-coverage/flow-model-coverage.csv b/java/documentation/library-coverage/flow-model-coverage.csv index a66f7880221..cf97071ad92 100644 --- a/java/documentation/library-coverage/flow-model-coverage.csv +++ b/java/documentation/library-coverage/flow-model-coverage.csv @@ -3,16 +3,16 @@ android.util,,16,,,,,,,,,,,16,, android.webkit,3,2,,,,,,,,,,3,2,, com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,1, com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,3,,,,,,,,,,,3, -com.google.common.base,,,34,,,,,,,,,,,28,6 -com.google.common.io,6,,73,,,,,,,6,,,,72,1 +com.fasterxml.jackson.databind,,,2,,,,,,,,,,,2, +com.google.common.base,,,28,,,,,,,,,,,22,6 +com.google.common.io,6,,69,,,,,,,6,,,,68,1 com.unboundid.ldap.sdk,17,,,,,,17,,,,,,,, java.beans,,,1,,,,,,,,,,,1, java.io,3,,20,,3,,,,,,,,,20, -java.lang,,,3,,,,,,,,,,,1,2 +java.lang,,,1,,,,,,,,,,,1, java.net,2,3,4,,,,,2,,,,,3,4, java.nio,10,,2,,10,,,,,,,,,2, -java.util,,,283,,,,,,,,,,,15,268 +java.util,,,13,,,,,,,,,,,13, javax.naming.directory,1,,,,,,1,,,,,,,, javax.net.ssl,2,,,,,,,,2,,,,,, javax.servlet,4,21,2,,,3,,,,,,1,21,2, @@ -23,14 +23,14 @@ javax.xml.transform.stream,,,2,,,,,,,,,,,2, javax.xml.xpath,3,,,,,,,,,,3,,,, org.apache.commons.codec,,,2,,,,,,,,,,,2, org.apache.commons.io,,,22,,,,,,,,,,,22, -org.apache.commons.lang3,,,327,,,,,,,,,,,311,16 -org.apache.commons.text,,,220,,,,,,,,,,,220, +org.apache.commons.lang3,,,313,,,,,,,,,,,299,14 +org.apache.commons.text,,,203,,,,,,,,,,,203, org.apache.directory.ldap.client.api,1,,,,,,1,,,,,,,, org.apache.hc.core5.function,,,1,,,,,,,,,,,1, org.apache.hc.core5.http,1,2,39,,,,,,,,,1,2,39, org.apache.hc.core5.net,,,2,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,18,6 -org.apache.http,2,3,67,,,,,,,,,2,3,59,8 +org.apache.hc.core5.util,,,22,,,,,,,,,,,18,4 +org.apache.http,2,3,66,,,,,,,,,2,3,59,7 org.dom4j,20,,,,,,,,,,20,,,, org.springframework.ldap.core,14,,,,,,14,,,,,,,, org.springframework.security.web.savedrequest,,6,,,,,,,,,,,6,, diff --git a/java/documentation/library-coverage/flow-model-coverage.rst b/java/documentation/library-coverage/flow-model-coverage.rst index 6e46c906b07..8bb20a9b6c3 100644 --- a/java/documentation/library-coverage/flow-model-coverage.rst +++ b/java/documentation/library-coverage/flow-model-coverage.rst @@ -8,12 +8,12 @@ Java framework & library support Framework / library,Package,Remote flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` Android,``android.*``,18,,3,,,3,,,, - Apache,``org.apache.*``,5,682,4,,,3,,1,, + Apache,``org.apache.*``,5,648,4,,,3,,1,, `Apache Commons IO `_,``org.apache.commons.io``,,22,,,,,,,, - Google,``com.google.common.*``,,107,6,,6,,,,, - Java Standard Library,``java.*``,3,313,15,13,,,,,,2 + Google,``com.google.common.*``,,97,6,,6,,,,, + Java Standard Library,``java.*``,3,41,15,13,,,,,,2 Java extensions,``javax.*``,22,8,12,,,1,,1,1, `Spring `_,``org.springframework.*``,29,,14,,,,,14,, - Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.dom4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,6,37,,,,,17,, - Totals,,84,1138,91,13,6,7,,33,1,2 + Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.dom4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,5,37,,,,,17,, + Totals,,84,821,91,13,6,7,,33,1,2 From 99708c33fd5347d9b7edba7346a04774dbab1e51 Mon Sep 17 00:00:00 2001 From: AlonaHlobina <54394529+AlonaHlobina@users.noreply.github.com> Date: Thu, 3 Jun 2021 09:50:18 +0200 Subject: [PATCH 101/272] Update versions-compilers.rst --- docs/codeql/support/reusables/versions-compilers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/support/reusables/versions-compilers.rst index f983b5e0114..52253cb5ab4 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/support/reusables/versions-compilers.rst @@ -28,7 +28,7 @@ .. [1] Support for the clang-cl compiler is preliminary. .. [2] Support for the Arm Compiler (armcc) is preliminary. - .. [3] Builds that execute on Java 7 to 15 can be analyzed. The analysis understands Java 15 standard language features. + .. [3] Builds that execute on Java 7 to 16 can be analyzed. The analysis understands Java 16 standard language features. .. [4] ECJ is supported when the build invokes it via the Maven Compiler plugin or the Takari Lifecycle plugin. .. [5] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. .. [6] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM. From 2833f8daa4092aa496c204c7313a1f42f19b3693 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 3 Jun 2021 10:42:41 +0200 Subject: [PATCH 102/272] Change predicate isUnsafeEngine -> isSafeEngine to improve performance --- .../src/semmle/code/java/security/JexlInjection.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/src/semmle/code/java/security/JexlInjection.qll b/java/ql/src/semmle/code/java/security/JexlInjection.qll index d36fa0aad9b..b975e6f2bdb 100644 --- a/java/ql/src/semmle/code/java/security/JexlInjection.qll +++ b/java/ql/src/semmle/code/java/security/JexlInjection.qll @@ -83,7 +83,7 @@ private class DefaultJexlInjectionAdditionalTaintStep extends JexlInjectionAddit */ private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | - isUnsafeEngine(ma.getQualifier()) and + not isSafeEngine(ma.getQualifier()) and m instanceof CreateJexlScriptMethod and n1.asExpr() = ma.getArgument(0) and n1.asExpr().getType() instanceof TypeString @@ -96,7 +96,7 @@ private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { */ private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | - isUnsafeEngine(ma.getQualifier()) and + not isSafeEngine(ma.getQualifier()) and m instanceof CreateJexlExpressionMethod and n1.asExpr() = ma.getAnArgument() and n1.asExpr().getType() instanceof TypeString @@ -111,7 +111,7 @@ private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma, Method m, RefType taintType | m = ma.getMethod() and n2.asExpr() = ma and taintType = n1.asExpr().getType() | - isUnsafeEngine(ma.getQualifier()) and + not isSafeEngine(ma.getQualifier()) and m instanceof CreateJexlTemplateMethod and n1.asExpr() = ma.getArgument([0, 1]) and (taintType instanceof TypeString or taintType instanceof Reader) @@ -119,10 +119,10 @@ private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { } /** - * Holds if `expr` is a JEXL engine that is not configured with a sandbox. + * Holds if `expr` is a JEXL engine that is configured with a sandbox. */ -private predicate isUnsafeEngine(Expr expr) { - not exists(SandboxedJexlFlowConfig config | config.hasFlowTo(DataFlow::exprNode(expr))) +private predicate isSafeEngine(Expr expr) { + exists(SandboxedJexlFlowConfig config | config.hasFlowTo(DataFlow::exprNode(expr))) } /** From 00836c4bacbbd2ad127849eacc57fafb71b99f14 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 3 Jun 2021 10:52:52 +0200 Subject: [PATCH 103/272] Fix QLDocs --- java/ql/src/semmle/code/java/security/JexlInjection.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/src/semmle/code/java/security/JexlInjection.qll b/java/ql/src/semmle/code/java/security/JexlInjection.qll index b975e6f2bdb..8e8923a746b 100644 --- a/java/ql/src/semmle/code/java/security/JexlInjection.qll +++ b/java/ql/src/semmle/code/java/security/JexlInjection.qll @@ -6,7 +6,7 @@ private import semmle.code.java.dataflow.ExternalFlow /** * A sink for Expresssion Language injection vulnerabilities via Jexl, - * i.e. method calls that run evaluation of a JEXL expression. + * that is, method calls that run evaluation of a JEXL expression. */ abstract class JexlEvaluationSink extends DataFlow::ExprNode { } @@ -79,7 +79,7 @@ private class DefaultJexlInjectionAdditionalTaintStep extends JexlInjectionAddit /** * Holds if `n1` to `n2` is a dataflow step that creates a JEXL script using an unsafe engine - * i.e. `tainted.createScript(jexlExpr)`. + * by calling `tainted.createScript(jexlExpr)`. */ private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | @@ -92,7 +92,7 @@ private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { /** * Holds if `n1` to `n2` is a dataflow step that creates a JEXL expression using an unsafe engine - * i.e. `tainted.createExpression(jexlExpr)`. + * by calling `tainted.createExpression(jexlExpr)`. */ private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | @@ -105,7 +105,7 @@ private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) /** * Holds if `n1` to `n2` is a dataflow step that creates a JEXL template using an unsafe engine - * i.e. `tainted.createTemplate(jexlExpr)`. + * by calling `tainted.createTemplate(jexlExpr)`. */ private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma, Method m, RefType taintType | From 85d9483c7b412728eb7624570d07299c15070fe8 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 12 May 2021 12:11:25 +0200 Subject: [PATCH 104/272] Python: Add basic aiohttp tests --- .../frameworks/aiohttp/ConceptsTest.expected | 0 .../frameworks/aiohttp/ConceptsTest.ql | 12 ++ .../aiohttp/InlineTaintTest.expected | 3 + .../frameworks/aiohttp/InlineTaintTest.ql | 1 + .../library-tests/frameworks/aiohttp/options | 1 + .../frameworks/aiohttp/response_test.py | 0 .../frameworks/aiohttp/routing_test.py | 169 ++++++++++++++++++ .../frameworks/aiohttp/taint_test.py | 0 8 files changed, 186 insertions(+) create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/options create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/response_test.py create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/routing_test.py create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/taint_test.py diff --git a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.ql new file mode 100644 index 00000000000..1e2c1fab3ee --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.ql @@ -0,0 +1,12 @@ +import python +import experimental.meta.ConceptsTest + +class DedicatedResponseTest extends HttpServerHttpResponseTest { + DedicatedResponseTest() { file.getShortName() = "response_test.py" } +} + +class OtherResponseTest extends HttpServerHttpResponseTest { + OtherResponseTest() { not this instanceof DedicatedResponseTest } + + override string getARelevantTag() { result = "HttpResponse" } +} diff --git a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected new file mode 100644 index 00000000000..79d760d87f4 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected @@ -0,0 +1,3 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +failures diff --git a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql new file mode 100644 index 00000000000..027ad8667be --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql @@ -0,0 +1 @@ +import experimental.meta.InlineTaintTest diff --git a/python/ql/test/library-tests/frameworks/aiohttp/options b/python/ql/test/library-tests/frameworks/aiohttp/options new file mode 100644 index 00000000000..cfef58cf2b2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiohttp/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --lang=3 diff --git a/python/ql/test/library-tests/frameworks/aiohttp/response_test.py b/python/ql/test/library-tests/frameworks/aiohttp/response_test.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py new file mode 100644 index 00000000000..6a8b98cfca6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -0,0 +1,169 @@ +# Inspired by https://docs.aiohttp.org/en/stable/web_quickstart.html +# and https://docs.aiohttp.org/en/stable/web_quickstart.html#resources-and-routes + +from aiohttp import web + + +app = web.Application() + + +## ================================= ## +## Ways to specify routes / handlers ## +## ================================= ## + +## Using coroutines +if True: + + # `app.add_routes` with list + async def foo(request): # $ MISSING: requestHandler + return web.Response(text="foo") + + async def foo2(request): # $ MISSING: requestHandler + return web.Response(text="foo2") + + async def foo3(request): # $ MISSING: requestHandler + return web.Response(text="foo3") + + app.add_routes([ + web.get("/foo", foo), # $ MISSING: routeSetup + web.route("*", "/foo2", foo2), # $ MISSING: routeSetup + web.get(path="/foo3", handler=foo3), # $ MISSING: routeSetup + ]) + + + # using decorator + routes = web.RouteTableDef() + + @routes.get("/bar") # $ MISSING: routeSetup + async def bar(request): # $ MISSING: requestHandler + return web.Response(text="bar") + + @routes.route("*", "/bar2") # $ MISSING: routeSetup + async def bar2(request): # $ MISSING: requestHandler + return web.Response(text="bar2") + + @routes.get(path="/bar3") # $ MISSING: routeSetup + async def bar3(request): # $ MISSING: requestHandler + return web.Response(text="bar3") + + app.add_routes(routes) + + + # `app.router.add_get` / `app.router.add_route` + async def baz(request): # $ MISSING: requestHandler + return web.Response(text="baz") + + app.router.add_get("/baz", baz) # $ MISSING: routeSetup + + async def baz2(request): # $ MISSING: requestHandler + return web.Response(text="baz2") + + app.router.add_route("*", "/baz2", baz2) # $ MISSING: routeSetup + + async def baz3(request): # $ MISSING: requestHandler + return web.Response(text="baz3") + + app.router.add_get(path="/baz3", handler=baz3) # $ MISSING: routeSetup + + +## Using classes / views +if True: + # see https://docs.aiohttp.org/en/stable/web_quickstart.html#organizing-handlers-in-classes + + class MyCustomHandlerClass: + + async def foo_handler(self, request): # $ MISSING: requestHandler + return web.Response(text="MyCustomHandlerClass.foo") + + my_custom_handler = MyCustomHandlerClass() + app.router.add_get("/MyCustomHandlerClass/foo", my_custom_handler.foo_handler) # $ MISSING: routeSetup + + # Using `web.View` + # --------------- + + # `app.add_routes` with list + class MyWebView1(web.View): + async def get(self): # $ MISSING: requestHandler + return web.Response(text="MyWebView1.get") + + app.add_routes([ + web.view("/MyWebView1", MyWebView1) # $ MISSING: routeSetup + ]) + + + # using decorator + routes = web.RouteTableDef() + + @routes.view("/MyWebView2") # $ MISSING: routeSetup + class MyWebView2(web.View): + async def get(self): # $ MISSING: requestHandler + return web.Response(text="MyWebView2.get") + + app.add_routes(routes) + + + # `app.router.add_view` + class MyWebView3(web.View): + async def get(self): # $ MISSING: requestHandler + return web.Response(text="MyWebView3.get") + + app.router.add_view("/MyWebView3", MyWebView3) # $ MISSING: routeSetup + +## =================== ## +## "Routed parameters" ## +## =================== ## + +if True: + # see https://docs.aiohttp.org/en/stable/web_quickstart.html#variable-resources + + async def matching(request: web.Request): # $ MISSING: requestHandler + name = request.match_info['name'] + number = request.match_info['number'] + return web.Response(text="matching name={} number={}".format(name, number)) + + app.router.add_get("/matching/{name}/{number:\d+}", matching) # $ MISSING: routeSetup + +## ======= ## +## subapps ## +## ======= ## + +if True: + subapp = web.Application() + + async def subapp_handler(request): # $ MISSING: requestHandler + return web.Response(text="subapp_handler") + + subapp.router.add_get("/subapp_handler", subapp_handler) # $ MISSING: routeSetup + + app.add_subapp("/my_subapp", subapp) + + # similar behavior is possible with `app.add_domain`, but since I don't think we'll have special handling + # for any kind of subapps, I have not created a test for this. + + +## ================================ ## +## Constructing UrlDispatcher first ## +## ================================ ## + +if True: + async def manual_dispatcher_instance(request): # $ MISSING: requestHandler + return web.Response(text="manual_dispatcher_instance") + + url_dispatcher = web.UrlDispatcher() + url_dispatcher.add_get("/manual_dispatcher_instance", manual_dispatcher_instance) # $ MISSING: routeSetup + + subapp2 = web.Application(router=url_dispatcher) + app.add_subapp("/manual_dispatcher_instance_app", subapp2) + + +## =========== ## +## Run the app ## +## =========== ## + +if __name__ == "__main__": + print("For auto-reloading server you can use:") + print(f"aiohttp-devtools runserver {__file__}") + print("after doing `pip install aiohttp-devtools`") + print() + + web.run_app(app) diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py new file mode 100644 index 00000000000..e69de29bb2d From fa1d4e6de781c935ba5894a52a6ce758fdfff17e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 20 May 2021 10:59:06 +0200 Subject: [PATCH 105/272] Python: Extract poor mans function resolution (from django) Since I also want to use this for aiohttp.web modeling --- .../src/semmle/python/frameworks/Django.qll | 51 +---------- .../internal/PoorMansFunctionResolution.qll | 90 +++++++++++++++++++ 2 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 python/ql/src/semmle/python/frameworks/internal/PoorMansFunctionResolution.qll diff --git a/python/ql/src/semmle/python/frameworks/Django.qll b/python/ql/src/semmle/python/frameworks/Django.qll index 93aa921e496..f1ae74bc8b5 100644 --- a/python/ql/src/semmle/python/frameworks/Django.qll +++ b/python/ql/src/semmle/python/frameworks/Django.qll @@ -11,6 +11,7 @@ private import semmle.python.Concepts private import semmle.python.ApiGraphs private import semmle.python.frameworks.PEP249 private import semmle.python.regex +private import semmle.python.frameworks.internal.PoorMansFunctionResolution /** * Provides models for the `django` PyPI package. @@ -1386,13 +1387,6 @@ private module PrivateDjango { // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- - /** - * Gets the last decorator call for the function `func`, if `func` has decorators. - */ - private Expr lastDecoratorCall(Function func) { - result = func.getDefinition().(FunctionExpr).getADecoratorCall() and - not exists(Call other_decorator | other_decorator.getArg(0) = result) - } /** Adds the `getASelfRef` member predicate when modeling a class. */ abstract private class SelfRefMixin extends Class { @@ -1487,45 +1481,6 @@ private module PrivateDjango { // --------------------------------------------------------------------------- // routing modeling // --------------------------------------------------------------------------- - /** - * Gets a reference to the Function `func`. - * - * The idea is that this function should be used as a route handler when setting up a - * route, but currently it just tracks all functions, since we can't do type-tracking - * backwards yet (TODO). - */ - private DataFlow::LocalSourceNode djangoRouteHandlerFunctionTracker( - DataFlow::TypeTracker t, Function func - ) { - t.start() and - ( - not exists(func.getADecorator()) and - result.asExpr() = func.getDefinition() - or - // If the function has decorators, we still want to model the function as being - // the request handler for a route setup. In such situations, we must track the - // last decorator call instead of the function itself. - // - // Note that this means that we blindly ignore what the decorator actually does to - // the function, which seems like an OK tradeoff. - result.asExpr() = lastDecoratorCall(func) - ) - or - exists(DataFlow::TypeTracker t2 | - result = djangoRouteHandlerFunctionTracker(t2, func).track(t2, t) - ) - } - - /** - * Gets a reference to the Function `func`. - * - * The idea is that this function should be used as a route handler when setting up a - * route, but currently it just tracks all functions, since we can't do type-tracking - * backwards yet (TODO). - */ - private DataFlow::Node djangoRouteHandlerFunctionTracker(Function func) { - djangoRouteHandlerFunctionTracker(DataFlow::TypeTracker::end(), func).flowsTo(result) - } /** * In order to recognize a class as being a django view class, based on the `as_view` @@ -1613,7 +1568,7 @@ private module PrivateDjango { */ private class DjangoRouteHandler extends Function { DjangoRouteHandler() { - exists(DjangoRouteSetup route | route.getViewArg() = djangoRouteHandlerFunctionTracker(this)) + exists(DjangoRouteSetup route | route.getViewArg() = poorMansFunctionTracker(this)) or any(DjangoViewClass vc).getARequestHandler() = this } @@ -1663,7 +1618,7 @@ private module PrivateDjango { abstract DataFlow::Node getViewArg(); final override DjangoRouteHandler getARequestHandler() { - djangoRouteHandlerFunctionTracker(result) = getViewArg() + poorMansFunctionTracker(result) = getViewArg() or exists(DjangoViewClass vc | getViewArg() = vc.asViewResult() and diff --git a/python/ql/src/semmle/python/frameworks/internal/PoorMansFunctionResolution.qll b/python/ql/src/semmle/python/frameworks/internal/PoorMansFunctionResolution.qll new file mode 100644 index 00000000000..78764bf53bc --- /dev/null +++ b/python/ql/src/semmle/python/frameworks/internal/PoorMansFunctionResolution.qll @@ -0,0 +1,90 @@ +/** + * INTERNAL: Do not use. + * + * Notice: The predicates provided in this module is a poor mans solution for function + * resolution, and does not handle anything but the most simple cases. + * + * For example, in the code below, we're not able to tell anything about + * `inst.my_method` (which is a bound-method) + * ```py + * class MyClass: + * def my_method(self): + * pass + * + * inst = MyClass() + * print(inst.my_method) + * ``` + */ + +private import python +private import semmle.python.dataflow.new.DataFlow + +/** + * Gets the last decorator call for the function `func`, if `func` has decorators. + */ +private Expr lastDecoratorCall(Function func) { + result = func.getDefinition().(FunctionExpr).getADecoratorCall() and + not exists(Call other_decorator | other_decorator.getArg(0) = result) +} + +/** + * Gets a reference to the Function `func`. + * + * Notice: This is a poor mans solution for function resolution, and does not handle + * anything but the most simple cases. + * + * For example, in the code below, we're not able to tell anything about + * `inst.my_method` (which is a bound-method) + * ```py + * class MyClass: + * def my_method(self): + * pass + * + * inst = MyClass() + * print(inst.my_method) + * ``` + */ +private DataFlow::LocalSourceNode poorMansFunctionTracker( + DataFlow::TypeTracker t, Function func +) { + t.start() and + ( + not exists(func.getADecorator()) and + result.asExpr() = func.getDefinition() + or + // If the function has decorators, we still want to model the function as being + // the request handler for a route setup. In such situations, we must track the + // last decorator call instead of the function itself. + // + // Note that this means that we blindly ignore what the decorator actually does to + // the function, which seems like an OK tradeoff. + result.asExpr() = lastDecoratorCall(func) + ) + or + exists(DataFlow::TypeTracker t2 | + result = poorMansFunctionTracker(t2, func).track(t2, t) + ) +} + +/** + * INTERNAL: Do not use. + * + * Gets a reference to the Function `func`. + * + * Notice: This is a poor mans solution for function resolution, and does not handle + * anything but the most simple cases. + * + * For example, in the code below, we're not able to tell anything about + * `inst.my_method` (which is a bound-method) + * ```py + * class MyClass: + * def my_method(self): + * pass + * + * inst = MyClass() + * print(inst.my_method) + * ``` + */ +DataFlow::Node poorMansFunctionTracker(Function func) { + poorMansFunctionTracker(DataFlow::TypeTracker::end(), func).flowsTo(result) +} From 3cbb909a3a4ae8f736d10bd3e1175f1a388c6af3 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 20 May 2021 11:12:28 +0200 Subject: [PATCH 106/272] Python: Add modeling of coroutine routes in aiohttp.web --- docs/codeql/support/reusables/frameworks.rst | 1 + python/ql/src/semmle/python/Frameworks.qll | 1 + .../src/semmle/python/frameworks/Aiohttp.qll | 141 ++++++++++++++++++ .../frameworks/aiohttp/routing_test.py | 50 +++---- 4 files changed, 168 insertions(+), 25 deletions(-) create mode 100644 python/ql/src/semmle/python/frameworks/Aiohttp.qll diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index be9949aad77..41680cffe0e 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -152,6 +152,7 @@ Python built-in support :widths: auto Name, Category + aiohttp.web, Web framework Django, Web framework Flask, Web framework Tornado, Web framework diff --git a/python/ql/src/semmle/python/Frameworks.qll b/python/ql/src/semmle/python/Frameworks.qll index 3115c3ffac6..172f3d11bfb 100644 --- a/python/ql/src/semmle/python/Frameworks.qll +++ b/python/ql/src/semmle/python/Frameworks.qll @@ -4,6 +4,7 @@ // If you add modeling of a new framework/library, remember to add it it to the docs in // `docs/codeql/support/reusables/frameworks.rst` +private import semmle.python.frameworks.Aiohttp private import semmle.python.frameworks.Cryptodome private import semmle.python.frameworks.Cryptography private import semmle.python.frameworks.Dill diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll new file mode 100644 index 00000000000..b73610c06b1 --- /dev/null +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -0,0 +1,141 @@ +/** + * Provides classes modeling security-relevant aspects of the `aiohttp` PyPI package. + * See https://docs.aiohttp.org/en/stable/index.html + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.frameworks.internal.PoorMansFunctionResolution + +/** + * INTERNAL: Do not use. + * + * Provides models for the web server part (`aiohttp.web`) of the `aiohttp` PyPI package. + * See https://docs.aiohttp.org/en/stable/web.html + */ +module AiohttpWebModel { + /** Gets a reference to a `aiohttp.web.Application` instance. */ + API::Node applicationInstance() { + // Not sure whether you're allowed to add routes _after_ starting the app, for + // example in the middle of handling a http request... but I'm guessing that for 99% + // for all code, not modeling that `request.app` is a reference to an application + // should be good enough for the route-setup part of the modeling :+1: + result = API::moduleImport("aiohttp").getMember("web").getMember("Application").getReturn() + } + + /** Gets a reference to a `aiohttp.web.UrlDispatcher` instance. */ + API::Node urlDispathcerInstance() { + result = API::moduleImport("aiohttp").getMember("web").getMember("UrlDispatcher").getReturn() + or + result = applicationInstance().getMember("router") + } + + // -- route modeling -- + + /** A route setup in `aiohttp.web` */ + abstract class AiohttpRouteSetup extends HTTP::Server::RouteSetup::Range { + override Parameter getARoutedParameter() { none() } + + override string getFramework() { result = "aiohttp.web" } + } + + /** An aiohttp route setup that uses coroutines (async function) as request handler. */ + abstract class AiohttpCoroutineRouteSetup extends AiohttpRouteSetup { + /** Gets the argument specifying the request handler (which is a coroutine/async function) */ + abstract DataFlow::Node getRequestHandlerArg(); + + override Function getARequestHandler() { + this.getRequestHandlerArg() = poorMansFunctionTracker(result) + } + } + + /** + * A route-setup from `add_route` or any of `add_get`, `add_post`, etc. on an + * `aiohttp.web.UrlDispatcher`. + */ + class AiohttpUrlDispatcherAddRouteCall extends AiohttpCoroutineRouteSetup, DataFlow::CallCfgNode { + /** At what index route arguments starts, so we can handle "route" version together with get/post/... */ + int routeArgsStart; + + AiohttpUrlDispatcherAddRouteCall() { + this = urlDispathcerInstance().getMember("add_" + HTTP::httpVerbLower()).getACall() and + routeArgsStart = 0 + or + this = urlDispathcerInstance().getMember("add_route").getACall() and + routeArgsStart = 1 + } + + override DataFlow::Node getUrlPatternArg() { + result in [this.getArg(routeArgsStart + 0), this.getArgByName("path")] + } + + override DataFlow::Node getRequestHandlerArg() { + result in [this.getArg(routeArgsStart + 1), this.getArgByName("handler")] + } + } + + /** + * A route-setup from using `route` or any of `get`, `post`, etc. functions from `aiohttp.web`. + * + * Note that technically, this does not set up a route in itself (since it needs to be added to an application first). + * However, modeling this way makes it easier, and we don't expect it to lead to many problems. + */ + class AiohttpWebRouteCall extends AiohttpCoroutineRouteSetup, DataFlow::CallCfgNode { + /** At what index route arguments starts, so we can handle "route" version together with get/post/... */ + int routeArgsStart; + + AiohttpWebRouteCall() { + exists(string funcName | + funcName = HTTP::httpVerbLower() and + routeArgsStart = 0 + or + funcName = "route" and + routeArgsStart = 1 + | + this = API::moduleImport("aiohttp").getMember("web").getMember(funcName).getACall() + ) + } + + override DataFlow::Node getUrlPatternArg() { + result in [this.getArg(routeArgsStart + 0), this.getArgByName("path")] + } + + override DataFlow::Node getRequestHandlerArg() { + result in [this.getArg(routeArgsStart + 1), this.getArgByName("handler")] + } + } + + /** A route-setup from using a `route` or any of `get`, `post`, etc. decorators from a `aiohttp.web.RouteTableDef`. */ + class AiohttpRouteTableDefRouteCall extends AiohttpCoroutineRouteSetup, DataFlow::CallCfgNode { + /** At what index route arguments starts, so we can handle "route" version together with get/post/... */ + int routeArgsStart; + + AiohttpRouteTableDefRouteCall() { + exists(string decoratorName | + decoratorName = HTTP::httpVerbLower() and + routeArgsStart = 0 + or + decoratorName = "route" and + routeArgsStart = 1 + | + this = + API::moduleImport("aiohttp") + .getMember("web") + .getMember("RouteTableDef") + .getReturn() + .getMember(decoratorName) + .getACall() + ) + } + + override DataFlow::Node getUrlPatternArg() { + result in [this.getArg(routeArgsStart + 0), this.getArgByName("path")] + } + + override DataFlow::Node getRequestHandlerArg() { none() } + + override Function getARequestHandler() { result.getADecorator() = this.asExpr() } + } +} diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py index 6a8b98cfca6..880a7f8cb87 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -15,55 +15,55 @@ app = web.Application() if True: # `app.add_routes` with list - async def foo(request): # $ MISSING: requestHandler + async def foo(request): # $ requestHandler return web.Response(text="foo") - async def foo2(request): # $ MISSING: requestHandler + async def foo2(request): # $ requestHandler return web.Response(text="foo2") - async def foo3(request): # $ MISSING: requestHandler + async def foo3(request): # $ requestHandler return web.Response(text="foo3") app.add_routes([ - web.get("/foo", foo), # $ MISSING: routeSetup - web.route("*", "/foo2", foo2), # $ MISSING: routeSetup - web.get(path="/foo3", handler=foo3), # $ MISSING: routeSetup + web.get("/foo", foo), # $ routeSetup="/foo" + web.route("*", "/foo2", foo2), # $ routeSetup="/foo2" + web.get(path="/foo3", handler=foo3), # $ routeSetup="/foo3" ]) # using decorator routes = web.RouteTableDef() - @routes.get("/bar") # $ MISSING: routeSetup - async def bar(request): # $ MISSING: requestHandler + @routes.get("/bar") # $ routeSetup="/bar" + async def bar(request): # $ requestHandler return web.Response(text="bar") - @routes.route("*", "/bar2") # $ MISSING: routeSetup - async def bar2(request): # $ MISSING: requestHandler + @routes.route("*", "/bar2") # $ routeSetup="/bar2" + async def bar2(request): # $ requestHandler return web.Response(text="bar2") - @routes.get(path="/bar3") # $ MISSING: routeSetup - async def bar3(request): # $ MISSING: requestHandler + @routes.get(path="/bar3") # $ routeSetup="/bar3" + async def bar3(request): # $ requestHandler return web.Response(text="bar3") app.add_routes(routes) # `app.router.add_get` / `app.router.add_route` - async def baz(request): # $ MISSING: requestHandler + async def baz(request): # $ requestHandler return web.Response(text="baz") - app.router.add_get("/baz", baz) # $ MISSING: routeSetup + app.router.add_get("/baz", baz) # $ routeSetup="/baz" - async def baz2(request): # $ MISSING: requestHandler + async def baz2(request): # $ requestHandler return web.Response(text="baz2") - app.router.add_route("*", "/baz2", baz2) # $ MISSING: routeSetup + app.router.add_route("*", "/baz2", baz2) # $ routeSetup="/baz2" - async def baz3(request): # $ MISSING: requestHandler + async def baz3(request): # $ requestHandler return web.Response(text="baz3") - app.router.add_get(path="/baz3", handler=baz3) # $ MISSING: routeSetup + app.router.add_get(path="/baz3", handler=baz3) # $ routeSetup="/baz3" ## Using classes / views @@ -76,7 +76,7 @@ if True: return web.Response(text="MyCustomHandlerClass.foo") my_custom_handler = MyCustomHandlerClass() - app.router.add_get("/MyCustomHandlerClass/foo", my_custom_handler.foo_handler) # $ MISSING: routeSetup + app.router.add_get("/MyCustomHandlerClass/foo", my_custom_handler.foo_handler) # $ routeSetup="/MyCustomHandlerClass/foo" # Using `web.View` # --------------- @@ -116,12 +116,12 @@ if True: if True: # see https://docs.aiohttp.org/en/stable/web_quickstart.html#variable-resources - async def matching(request: web.Request): # $ MISSING: requestHandler + async def matching(request: web.Request): # $ requestHandler name = request.match_info['name'] number = request.match_info['number'] return web.Response(text="matching name={} number={}".format(name, number)) - app.router.add_get("/matching/{name}/{number:\d+}", matching) # $ MISSING: routeSetup + app.router.add_get(r"/matching/{name}/{number:\d+}", matching) # $ routeSetup="/matching/{name}/{number:\d+}" ## ======= ## ## subapps ## @@ -130,10 +130,10 @@ if True: if True: subapp = web.Application() - async def subapp_handler(request): # $ MISSING: requestHandler + async def subapp_handler(request): # $ requestHandler return web.Response(text="subapp_handler") - subapp.router.add_get("/subapp_handler", subapp_handler) # $ MISSING: routeSetup + subapp.router.add_get("/subapp_handler", subapp_handler) # $ routeSetup="/subapp_handler" app.add_subapp("/my_subapp", subapp) @@ -146,11 +146,11 @@ if True: ## ================================ ## if True: - async def manual_dispatcher_instance(request): # $ MISSING: requestHandler + async def manual_dispatcher_instance(request): # $ requestHandler return web.Response(text="manual_dispatcher_instance") url_dispatcher = web.UrlDispatcher() - url_dispatcher.add_get("/manual_dispatcher_instance", manual_dispatcher_instance) # $ MISSING: routeSetup + url_dispatcher.add_get("/manual_dispatcher_instance", manual_dispatcher_instance) # $ routeSetup="/manual_dispatcher_instance" subapp2 = web.Application(router=url_dispatcher) app.add_subapp("/manual_dispatcher_instance_app", subapp2) From 2b992a635a1c3ff42d45b826353a919f7f0d4aa5 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 26 May 2021 14:54:20 +0200 Subject: [PATCH 107/272] Python: Add aiohttp taint tests --- .../frameworks/aiohttp/taint_test.py | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index e69de29bb2d..ba24f59a702 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -0,0 +1,196 @@ +from aiohttp import web + +async def test_taint(request: web.Request): # $ requestHandler + + ensure_tainted( + request, # $ MISSING: tainted + + # yarl.URL instances + # https://yarl.readthedocs.io/en/stable/api.html#yarl.URL + # see below + request.url, # $ MISSING: tainted + request.rel_url, # $ MISSING: tainted + + request.forwarded, # $ MISSING: tainted + + request.host, # $ MISSING: tainted + request.remote, # $ MISSING: tainted + request.path, # $ MISSING: tainted + request.path_qs, # $ MISSING: tainted + request.raw_path, # $ MISSING: tainted + + # multidict.MultiDictProxy[str] + # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.MultiDictProxy + # TODO: Should have a better way to capture that we in fact _do_ model this as a + # an instance of the right class, and have the actual taint_test for that in a + # different file! + request.query, # $ MISSING: tainted + request.query["key"], # $ MISSING: tainted + request.query.get("key"), # $ MISSING: tainted + request.query.getone("key"), # $ MISSING: tainted + request.query.getall("key"), # $ MISSING: tainted + request.query.keys(), # $ MISSING: tainted + request.query.values(), # $ MISSING: tainted + request.query.items(), # $ MISSING: tainted + request.query.copy(), # $ MISSING: tainted + list(request.query), # $ MISSING: tainted + iter(request.query), # $ MISSING: tainted + + # multidict.CIMultiDictProxy[str] + # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.CIMultiDictProxy + # TODO: Should have a better way to capture that we in fact _do_ model this as a + # an instance of the right class, and have the actual taint_test for that in a + # different file! + request.headers, # $ MISSING: tainted + request.query.getone("key"), # $ MISSING: tainted + + # https://docs.python.org/3/library/asyncio-protocol.html#asyncio-transport + # TODO + request.transport, # $ MISSING: tainted + request.transport.get_extra_info("key"), # $ MISSING: tainted + + # dict-like (readonly) + request.cookies, # $ MISSING: tainted + request.cookies["key"], # $ MISSING: tainted + request.cookies.get("key"), # $ MISSING: tainted + request.cookies.keys(), # $ MISSING: tainted + request.cookies.values(), # $ MISSING: tainted + request.cookies.items(), # $ MISSING: tainted + list(request.cookies), # $ MISSING: tainted + iter(request.cookies), # $ MISSING: tainted + + + # aiohttp.StreamReader + # see https://docs.aiohttp.org/en/stable/streams.html#aiohttp.StreamReader + # TODO + request.content, # $ MISSING: tainted + request._payload, # $ MISSING: tainted + + request.body_exists, # $ MISSING: tainted + request.has_body, # $ MISSING: tainted + + request.content_type, # $ MISSING: tainted + request.charset, # $ MISSING: tainted + + request.http_range, # $ MISSING: tainted + + # Optional[datetime] + request.if_modified_since, # $ MISSING: tainted + request.if_unmodified_since, # $ MISSING: tainted + request.if_range, # $ MISSING: tainted + + request.clone(scheme="https"), # $ MISSING: tainted + + # TODO: like request.transport.get_extra_info + request.get_extra_info("key"), # $ MISSING: tainted + + # bytes + await request.read(), # $ MISSING: tainted + + # str + await request.text(), # $ MISSING: tainted + + # obj + await request.json(), # $ MISSING: tainted + + # aiohttp.multipart.MultipartReader + await request.multipart(), # $ MISSING: tainted + + # multidict.MultiDictProxy[str] + await request.post(), # $ MISSING: tainted + (await request.post()).getone("key"), # $ MISSING: tainted + ) + + import yarl + assert isinstance(request.url, yarl.URL) + assert isinstance(request.rel_url, yarl.URL) + + + # things that are technically controlled by sender of request, + # but doesn't seem that likely for exploitation. + ensure_not_tainted( + request.method, + request.version, + request.scheme, + request.secure, + request.keep_alive, + + request.content_length, + ) + + ensure_not_tainted( + request.loop, + + request.match_info, + request.app, + request.config_dict, + ) + + # TODO: Should have a better way to capture that we in fact _do_ model this as a + # an instance of the right class, and have the actual taint_test for that in a + # different file! + import yarl + + ensure_tainted( + request.url.user, # $ MISSING: tainted + request.url.raw_user, # $ MISSING: tainted + + request.url.password, # $ MISSING: tainted + request.url.raw_password, # $ MISSING: tainted + + request.url.host, # $ MISSING: tainted + request.url.raw_host, # $ MISSING: tainted + + request.url.port, # $ MISSING: tainted + request.url.explicit_port, # $ MISSING: tainted + + request.url.authority, # $ MISSING: tainted + request.url.raw_authority, # $ MISSING: tainted + + request.url.path, # $ MISSING: tainted + request.url.raw_path, # $ MISSING: tainted + + request.url.path_qs, # $ MISSING: tainted + request.url.raw_path_qs, # $ MISSING: tainted + + request.url.query_string, # $ MISSING: tainted + request.url.raw_query_string, # $ MISSING: tainted + + request.url.fragment, # $ MISSING: tainted + request.url.raw_fragment, # $ MISSING: tainted + + request.url.parts, # $ MISSING: tainted + request.url.raw_parts, # $ MISSING: tainted + + request.url.name, # $ MISSING: tainted + request.url.raw_name, # $ MISSING: tainted + + # multidict.MultiDictProxy[str] + request.url.query, # $ MISSING: tainted + request.url.query.getone("key"), # $ MISSING: tainted + + request.url.with_scheme("foo"), # $ MISSING: tainted + request.url.with_user("foo"), # $ MISSING: tainted + request.url.with_password("foo"), # $ MISSING: tainted + request.url.with_host("foo"), # $ MISSING: tainted + request.url.with_port("foo"), # $ MISSING: tainted + request.url.with_path("foo"), # $ MISSING: tainted + request.url.with_query({"foo": 42}), # $ MISSING: tainted + request.url.with_query(foo=42), # $ MISSING: tainted + request.url.update_query({"foo": 42}), # $ MISSING: tainted + request.url.update_query(foo=42), # $ MISSING: tainted + request.url.with_fragment("foo"), # $ MISSING: tainted + request.url.with_name("foo"), # $ MISSING: tainted + + request.url.join(yarl.URL("wat.html")), # $ MISSING: tainted + + request.url.human_repr(), # $ MISSING: tainted + ) + + +app = web.Application() +app.router.add_get(r"/test_taint/{name}/{number:\d+}", test_taint) # $ routeSetup="/test_taint/{name}/{number:\d+}" + + +if __name__ == "__main__": + web.run_app(app) From 88158e7414ff45206a71b8f9a7cc84cea33d653c Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 26 May 2021 15:24:52 +0200 Subject: [PATCH 108/272] Python: Add basic model setup for aiohttp.web.Request --- .../src/semmle/python/frameworks/Aiohttp.qll | 67 ++++++++++++++++++- .../frameworks/aiohttp/taint_test.py | 2 +- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index b73610c06b1..e7131e2c409 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -5,6 +5,8 @@ private import python private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.dataflow.new.TaintTracking private import semmle.python.Concepts private import semmle.python.ApiGraphs private import semmle.python.frameworks.internal.PoorMansFunctionResolution @@ -33,7 +35,6 @@ module AiohttpWebModel { } // -- route modeling -- - /** A route setup in `aiohttp.web` */ abstract class AiohttpRouteSetup extends HTTP::Server::RouteSetup::Range { override Parameter getARoutedParameter() { none() } @@ -138,4 +139,68 @@ module AiohttpWebModel { override Function getARequestHandler() { result.getADecorator() = this.asExpr() } } + + // --------------------------------------------------------------------------- + // aiohttp.web.Request taint modeling + // --------------------------------------------------------------------------- + /** + * Provides models for the `aiohttp.web.Request` class + * + * See https://docs.aiohttp.org/en/stable/web_reference.html#request-and-base-request + */ + module Request { + /** + * A source of instances of `aiohttp.web.Request`, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use `Request::instance()` predicate to get + * references to instances of `aiohttp.web.Request`. + */ + abstract class InstanceSource extends DataFlow::Node { } + + /** Gets a reference to an instance of `aiohttp.web.Request`. */ + private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of `aiohttp.web.Request`. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + } + + /** + * A parameter that will receive a `aiohttp.web.Request` instance when a request + * handler is invoked. + */ + class AiohttpRequestHandlerRequestParam extends Request::InstanceSource, RemoteFlowSource::Range, + DataFlow::ParameterNode { + AiohttpRequestHandlerRequestParam() { + exists(Function requestHandler | + requestHandler = any(AiohttpRouteSetup setup).getARequestHandler() and + // We select the _last_ parameter for the request since that is what they do in + // `aiohttp-jinja2`. + // https://github.com/aio-libs/aiohttp-jinja2/blob/7fb4daf2c3003921d34031d38c2311ee0e02c18b/aiohttp_jinja2/__init__.py#L235 + // + // I assume that is just to handle cases such as the one below + // ```py + // class MyCustomHandlerClass: + // async def foo_handler(self, request): + // ... + // + // my_custom_handler = MyCustomHandlerClass() + // app.router.add_get("/MyCustomHandlerClass/foo", my_custom_handler.foo_handler) + // ``` + this.getParameter() = + max(Parameter param, int i | param = requestHandler.getArg(i) | param order by i) + + ) + } + + override string getSourceType() { result = "aiohttp.web.Request" } + } } diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index ba24f59a702..d996d07ead2 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -3,7 +3,7 @@ from aiohttp import web async def test_taint(request: web.Request): # $ requestHandler ensure_tainted( - request, # $ MISSING: tainted + request, # $ tainted # yarl.URL instances # https://yarl.readthedocs.io/en/stable/api.html#yarl.URL From d953ea47d4718d55300c273f409eb7b2168d4652 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 26 May 2021 15:53:33 +0200 Subject: [PATCH 109/272] Python: Basic handling of tainted attributes in aiohttp --- .../src/semmle/python/frameworks/Aiohttp.qll | 29 +++++++- .../frameworks/aiohttp/taint_test.py | 74 +++++++++---------- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index e7131e2c409..7e2c9dc8424 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -197,10 +197,37 @@ module AiohttpWebModel { // ``` this.getParameter() = max(Parameter param, int i | param = requestHandler.getArg(i) | param order by i) - ) } override string getSourceType() { result = "aiohttp.web.Request" } } + + /** + * Taint propagation for `aiohttp.web.Request`. + * + * See https://docs.aiohttp.org/en/stable/web_reference.html#request-and-base-request + */ + private class AiohttpRequestAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { + override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // Methods + exists(string method_name | method_name in ["TODO"] | + // Method access (obj -> obj.meth) + none() + or + // Method call (obj.meth -> obj.meth()) + none() + ) + or + // Attributes + nodeFrom = Request::instance() and + nodeTo.(DataFlow::AttrRead).getObject() = nodeFrom and + nodeTo.(DataFlow::AttrRead).getAttributeName() in [ + "url", "rel_url", "forwarded", "host", "remote", "path", "path_qs", "raw_path", "query", + "headers", "transport", "cookies", "content", "_payload", "body_exists", "has_body", + "content_type", "charset", "http_range", "if_modified_since", "if_unmodified_since", + "if_range" + ] + } + } } diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index d996d07ead2..39c814564ce 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -8,76 +8,76 @@ async def test_taint(request: web.Request): # $ requestHandler # yarl.URL instances # https://yarl.readthedocs.io/en/stable/api.html#yarl.URL # see below - request.url, # $ MISSING: tainted - request.rel_url, # $ MISSING: tainted + request.url, # $ tainted + request.rel_url, # $ tainted - request.forwarded, # $ MISSING: tainted + request.forwarded, # $ tainted - request.host, # $ MISSING: tainted - request.remote, # $ MISSING: tainted - request.path, # $ MISSING: tainted - request.path_qs, # $ MISSING: tainted - request.raw_path, # $ MISSING: tainted + request.host, # $ tainted + request.remote, # $ tainted + request.path, # $ tainted + request.path_qs, # $ tainted + request.raw_path, # $ tainted # multidict.MultiDictProxy[str] # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.MultiDictProxy # TODO: Should have a better way to capture that we in fact _do_ model this as a # an instance of the right class, and have the actual taint_test for that in a # different file! - request.query, # $ MISSING: tainted - request.query["key"], # $ MISSING: tainted - request.query.get("key"), # $ MISSING: tainted + request.query, # $ tainted + request.query["key"], # $ tainted + request.query.get("key"), # $ tainted request.query.getone("key"), # $ MISSING: tainted request.query.getall("key"), # $ MISSING: tainted request.query.keys(), # $ MISSING: tainted - request.query.values(), # $ MISSING: tainted - request.query.items(), # $ MISSING: tainted - request.query.copy(), # $ MISSING: tainted - list(request.query), # $ MISSING: tainted - iter(request.query), # $ MISSING: tainted + request.query.values(), # $ tainted + request.query.items(), # $ tainted + request.query.copy(), # $ tainted + list(request.query), # $ tainted + iter(request.query), # $ tainted # multidict.CIMultiDictProxy[str] # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.CIMultiDictProxy # TODO: Should have a better way to capture that we in fact _do_ model this as a # an instance of the right class, and have the actual taint_test for that in a # different file! - request.headers, # $ MISSING: tainted - request.query.getone("key"), # $ MISSING: tainted + request.headers, # $ tainted + request.headers.getone("key"), # $ MISSING: tainted # https://docs.python.org/3/library/asyncio-protocol.html#asyncio-transport # TODO - request.transport, # $ MISSING: tainted + request.transport, # $ tainted request.transport.get_extra_info("key"), # $ MISSING: tainted # dict-like (readonly) - request.cookies, # $ MISSING: tainted - request.cookies["key"], # $ MISSING: tainted - request.cookies.get("key"), # $ MISSING: tainted + request.cookies, # $ tainted + request.cookies["key"], # $ tainted + request.cookies.get("key"), # $ tainted request.cookies.keys(), # $ MISSING: tainted - request.cookies.values(), # $ MISSING: tainted - request.cookies.items(), # $ MISSING: tainted - list(request.cookies), # $ MISSING: tainted - iter(request.cookies), # $ MISSING: tainted + request.cookies.values(), # $ tainted + request.cookies.items(), # $ tainted + list(request.cookies), # $ tainted + iter(request.cookies), # $ tainted # aiohttp.StreamReader # see https://docs.aiohttp.org/en/stable/streams.html#aiohttp.StreamReader # TODO - request.content, # $ MISSING: tainted - request._payload, # $ MISSING: tainted + request.content, # $ tainted + request._payload, # $ tainted - request.body_exists, # $ MISSING: tainted - request.has_body, # $ MISSING: tainted + request.body_exists, # $ tainted + request.has_body, # $ tainted - request.content_type, # $ MISSING: tainted - request.charset, # $ MISSING: tainted + request.content_type, # $ tainted + request.charset, # $ tainted - request.http_range, # $ MISSING: tainted + request.http_range, # $ tainted # Optional[datetime] - request.if_modified_since, # $ MISSING: tainted - request.if_unmodified_since, # $ MISSING: tainted - request.if_range, # $ MISSING: tainted + request.if_modified_since, # $ tainted + request.if_unmodified_since, # $ tainted + request.if_range, # $ tainted request.clone(scheme="https"), # $ MISSING: tainted @@ -182,7 +182,7 @@ async def test_taint(request: web.Request): # $ requestHandler request.url.with_fragment("foo"), # $ MISSING: tainted request.url.with_name("foo"), # $ MISSING: tainted - request.url.join(yarl.URL("wat.html")), # $ MISSING: tainted + request.url.join(yarl.URL("wat.html")), # $ tainted request.url.human_repr(), # $ MISSING: tainted ) From 597a9dfc80051c3652132a2ecf59f9808ded98be Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 26 May 2021 15:57:02 +0200 Subject: [PATCH 110/272] Python: Don't consider has_body tainted Although it technically is, I think it belong in the section of things that are unlikely to be exploitable --- python/ql/src/semmle/python/frameworks/Aiohttp.qll | 5 ++--- .../ql/test/library-tests/frameworks/aiohttp/taint_test.py | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 7e2c9dc8424..1a2a8e64bf5 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -224,9 +224,8 @@ module AiohttpWebModel { nodeTo.(DataFlow::AttrRead).getObject() = nodeFrom and nodeTo.(DataFlow::AttrRead).getAttributeName() in [ "url", "rel_url", "forwarded", "host", "remote", "path", "path_qs", "raw_path", "query", - "headers", "transport", "cookies", "content", "_payload", "body_exists", "has_body", - "content_type", "charset", "http_range", "if_modified_since", "if_unmodified_since", - "if_range" + "headers", "transport", "cookies", "content", "_payload", "content_type", "charset", + "http_range", "if_modified_since", "if_unmodified_since", "if_range" ] } } diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 39c814564ce..a3d0e30fb42 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -66,9 +66,6 @@ async def test_taint(request: web.Request): # $ requestHandler request.content, # $ tainted request._payload, # $ tainted - request.body_exists, # $ tainted - request.has_body, # $ tainted - request.content_type, # $ tainted request.charset, # $ tainted @@ -116,6 +113,9 @@ async def test_taint(request: web.Request): # $ requestHandler request.keep_alive, request.content_length, + request.body_exists, + request.has_body, + request.can_read_body, ) ensure_not_tainted( From 63c7fa0c2ca12453c1a1fea16bd85c2ec55a23ea Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 26 May 2021 16:05:36 +0200 Subject: [PATCH 111/272] Python: aiohttp match_info should be tainted Whoops --- python/ql/src/semmle/python/frameworks/Aiohttp.qll | 2 +- .../ql/test/library-tests/frameworks/aiohttp/taint_test.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 1a2a8e64bf5..6455bf79c3c 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -225,7 +225,7 @@ module AiohttpWebModel { nodeTo.(DataFlow::AttrRead).getAttributeName() in [ "url", "rel_url", "forwarded", "host", "remote", "path", "path_qs", "raw_path", "query", "headers", "transport", "cookies", "content", "_payload", "content_type", "charset", - "http_range", "if_modified_since", "if_unmodified_since", "if_range" + "http_range", "if_modified_since", "if_unmodified_since", "if_range", "match_info" ] } } diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index a3d0e30fb42..33cee33c3a5 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -19,6 +19,11 @@ async def test_taint(request: web.Request): # $ requestHandler request.path_qs, # $ tainted request.raw_path, # $ tainted + # dict-like for captured parts of the URL + request.match_info, # $ tainted + request.match_info["key"], # $ tainted + request.match_info.get("key"), # $ tainted + # multidict.MultiDictProxy[str] # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.MultiDictProxy # TODO: Should have a better way to capture that we in fact _do_ model this as a @@ -121,7 +126,6 @@ async def test_taint(request: web.Request): # $ requestHandler ensure_not_tainted( request.loop, - request.match_info, request.app, request.config_dict, ) From dd131e6bf79c6458d1eece2c9e27d2abe1189edb Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 27 May 2021 10:28:07 +0200 Subject: [PATCH 112/272] Python: Add taint-step for methods on aiohttp.web.Request --- .../src/semmle/python/frameworks/Aiohttp.qll | 21 ++++++++++++++----- .../frameworks/aiohttp/taint_test.py | 14 ++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 6455bf79c3c..6f36f31a5b9 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -211,12 +211,23 @@ module AiohttpWebModel { private class AiohttpRequestAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // Methods - exists(string method_name | method_name in ["TODO"] | - // Method access (obj -> obj.meth) - none() + // + // TODO: When we have tools that make it easy, model these properly to handle + // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach + // (since it allows us to at least capture the most common cases). + nodeFrom = Request::instance() and + exists(DataFlow::AttrRead attr | attr.getObject() = nodeFrom | + // normal methods + attr.getAttributeName() in ["clone", "get_extra_info"] and + nodeTo.(DataFlow::CallCfgNode).getFunction() = attr or - // Method call (obj.meth -> obj.meth()) - none() + // async methods + exists(Await await, DataFlow::CallCfgNode call | + attr.getAttributeName() in ["read", "text", "json", "multipart", "post"] and + call.getFunction() = attr and + await.getValue() = call.asExpr() and + nodeTo.asExpr() = await + ) ) or // Attributes diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 33cee33c3a5..e16a2d79d66 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -81,25 +81,25 @@ async def test_taint(request: web.Request): # $ requestHandler request.if_unmodified_since, # $ tainted request.if_range, # $ tainted - request.clone(scheme="https"), # $ MISSING: tainted + request.clone(scheme="https"), # $ tainted # TODO: like request.transport.get_extra_info - request.get_extra_info("key"), # $ MISSING: tainted + request.get_extra_info("key"), # $ tainted # bytes - await request.read(), # $ MISSING: tainted + await request.read(), # $ tainted # str - await request.text(), # $ MISSING: tainted + await request.text(), # $ tainted # obj - await request.json(), # $ MISSING: tainted + await request.json(), # $ tainted # aiohttp.multipart.MultipartReader - await request.multipart(), # $ MISSING: tainted + await request.multipart(), # $ tainted # multidict.MultiDictProxy[str] - await request.post(), # $ MISSING: tainted + await request.post(), # $ tainted (await request.post()).getone("key"), # $ MISSING: tainted ) From e76f02b016cadd7f2a5852d665b91b37a686b40a Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 27 May 2021 10:29:39 +0200 Subject: [PATCH 113/272] Python: Minor refactor to use LocalSourceNode This just more correctly reflects the reality, since the type-tracking predicate just below only holds for LocalSourceNode anyway. --- python/ql/src/semmle/python/frameworks/Aiohttp.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 6f36f31a5b9..074c64dae8f 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -159,7 +159,7 @@ module AiohttpWebModel { * Use `Request::instance()` predicate to get * references to instances of `aiohttp.web.Request`. */ - abstract class InstanceSource extends DataFlow::Node { } + abstract class InstanceSource extends DataFlow::LocalSourceNode { } /** Gets a reference to an instance of `aiohttp.web.Request`. */ private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { @@ -240,4 +240,6 @@ module AiohttpWebModel { ] } } + + } From 72e6a1489c047d9a169695964923cd2f952cdfa2 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 27 May 2021 10:49:50 +0200 Subject: [PATCH 114/272] Python: Add taint-steps for MultiDictProxy --- docs/codeql/support/reusables/frameworks.rst | 3 +- python/ql/src/semmle/python/Frameworks.qll | 1 + .../src/semmle/python/frameworks/Aiohttp.qll | 8 ++- .../semmle/python/frameworks/Multidict.qll | 72 +++++++++++++++++++ .../frameworks/aiohttp/taint_test.py | 6 +- 5 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 python/ql/src/semmle/python/frameworks/Multidict.qll diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index 41680cffe0e..ac93993ec7d 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -161,8 +161,9 @@ Python built-in support simplejson, Serialization ujson, Serialization fabric, Utility library - invoke, Utility library idna, Utility library + invoke, Utility library + multidict, Utility library mysql-connector-python, Database MySQLdb, Database psycopg2, Database diff --git a/python/ql/src/semmle/python/Frameworks.qll b/python/ql/src/semmle/python/Frameworks.qll index 172f3d11bfb..065ec5d69f9 100644 --- a/python/ql/src/semmle/python/Frameworks.qll +++ b/python/ql/src/semmle/python/Frameworks.qll @@ -13,6 +13,7 @@ private import semmle.python.frameworks.Fabric private import semmle.python.frameworks.Flask private import semmle.python.frameworks.Idna private import semmle.python.frameworks.Invoke +private import semmle.python.frameworks.Multidict private import semmle.python.frameworks.MysqlConnectorPython private import semmle.python.frameworks.MySQLdb private import semmle.python.frameworks.Psycopg2 diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 074c64dae8f..0f2d3d5d18c 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -10,6 +10,7 @@ private import semmle.python.dataflow.new.TaintTracking private import semmle.python.Concepts private import semmle.python.ApiGraphs private import semmle.python.frameworks.internal.PoorMansFunctionResolution +private import semmle.python.frameworks.Multidict /** * INTERNAL: Do not use. @@ -241,5 +242,10 @@ module AiohttpWebModel { } } - + class AiohttpRequestMultiDictProxyInstances extends Multidict::MultiDictProxy::InstanceSource { + AiohttpRequestMultiDictProxyInstances() { + this.(DataFlow::AttrRead).getObject() = Request::instance() and + this.(DataFlow::AttrRead).getAttributeName() in ["query", "headers"] + } + } } diff --git a/python/ql/src/semmle/python/frameworks/Multidict.qll b/python/ql/src/semmle/python/frameworks/Multidict.qll new file mode 100644 index 00000000000..7a2c2bf0751 --- /dev/null +++ b/python/ql/src/semmle/python/frameworks/Multidict.qll @@ -0,0 +1,72 @@ +/** + * Provides classes modeling security-relevant aspects of the `multidict` PyPI package. + * See https://multidict.readthedocs.io/en/stable/. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.Concepts +private import semmle.python.ApiGraphs + +/** + * INTERNAL: Do not use. + * + * Provides models for the `multidict` PyPI package. + * See https://multidict.readthedocs.io/en/stable/. + */ +module Multidict { + /** + * Provides models for a `MultiDictProxy` class: + * - `multidict.MultiDictProxy` + * - `multidict.CIMultiDictProxy` + * + * See https://multidict.readthedocs.io/en/stable/multidict.html#multidictproxy + */ + module MultiDictProxy { + /** + * A source of instances of `multidict.MultiDictProxy`, extend this class to model + * new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use `MultiDictProxy::instance()` predicate to get + * references to instances of `multidict.MultiDictProxy`. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + /** Gets a reference to an instance of `multidict.MultiDictProxy`. */ + private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of `multidict.MultiDictProxy`. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** + * Taint propagation for `multidict.MultiDictProxy`. + * + * See https://multidict.readthedocs.io/en/stable/multidict.html#multidictproxy + */ + class MultiDictProxyAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { + override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // Methods + // + // TODO: When we have tools that make it easy, model these properly to handle + // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach + // (since it allows us to at least capture the most common cases). + nodeFrom = instance() and + exists(DataFlow::AttrRead attr | attr.getObject() = nodeFrom | + // methods (non-async) + attr.getAttributeName() in ["getone", "getall"] and + nodeTo.(DataFlow::CallCfgNode).getFunction() = attr + ) + } + } + } +} diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index e16a2d79d66..eab09f17e74 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -32,8 +32,8 @@ async def test_taint(request: web.Request): # $ requestHandler request.query, # $ tainted request.query["key"], # $ tainted request.query.get("key"), # $ tainted - request.query.getone("key"), # $ MISSING: tainted - request.query.getall("key"), # $ MISSING: tainted + request.query.getone("key"), # $ tainted + request.query.getall("key"), # $ tainted request.query.keys(), # $ MISSING: tainted request.query.values(), # $ tainted request.query.items(), # $ tainted @@ -47,7 +47,7 @@ async def test_taint(request: web.Request): # $ requestHandler # an instance of the right class, and have the actual taint_test for that in a # different file! request.headers, # $ tainted - request.headers.getone("key"), # $ MISSING: tainted + request.headers.getone("key"), # $ tainted # https://docs.python.org/3/library/asyncio-protocol.html#asyncio-transport # TODO From fb21bc04fa5c5d6996d387c99e1e7f3d22891252 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 27 May 2021 20:23:36 +0200 Subject: [PATCH 115/272] Python: Add taint-steps for `yarl.URL` --- docs/codeql/support/reusables/frameworks.rst | 1 + python/ql/src/semmle/python/Frameworks.qll | 1 + .../src/semmle/python/frameworks/Aiohttp.qll | 8 ++ .../ql/src/semmle/python/frameworks/Yarl.qll | 110 ++++++++++++++++++ .../frameworks/aiohttp/taint_test.py | 75 ++++++------ 5 files changed, 158 insertions(+), 37 deletions(-) create mode 100644 python/ql/src/semmle/python/frameworks/Yarl.qll diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index ac93993ec7d..d39b85931ce 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -164,6 +164,7 @@ Python built-in support idna, Utility library invoke, Utility library multidict, Utility library + yarl, Utility library mysql-connector-python, Database MySQLdb, Database psycopg2, Database diff --git a/python/ql/src/semmle/python/Frameworks.qll b/python/ql/src/semmle/python/Frameworks.qll index 065ec5d69f9..523f844954b 100644 --- a/python/ql/src/semmle/python/Frameworks.qll +++ b/python/ql/src/semmle/python/Frameworks.qll @@ -23,3 +23,4 @@ private import semmle.python.frameworks.Stdlib private import semmle.python.frameworks.Tornado private import semmle.python.frameworks.Ujson private import semmle.python.frameworks.Yaml +private import semmle.python.frameworks.Yarl diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 0f2d3d5d18c..c6616b93712 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -11,6 +11,7 @@ private import semmle.python.Concepts private import semmle.python.ApiGraphs private import semmle.python.frameworks.internal.PoorMansFunctionResolution private import semmle.python.frameworks.Multidict +private import semmle.python.frameworks.Yarl /** * INTERNAL: Do not use. @@ -248,4 +249,11 @@ module AiohttpWebModel { this.(DataFlow::AttrRead).getAttributeName() in ["query", "headers"] } } + + class AiohttpRequestYarlUrlInstances extends Yarl::Url::InstanceSource { + AiohttpRequestYarlUrlInstances() { + this.(DataFlow::AttrRead).getObject() = Request::instance() and + this.(DataFlow::AttrRead).getAttributeName() in ["url", "rel_url"] + } + } } diff --git a/python/ql/src/semmle/python/frameworks/Yarl.qll b/python/ql/src/semmle/python/frameworks/Yarl.qll new file mode 100644 index 00000000000..a998d8e0ca1 --- /dev/null +++ b/python/ql/src/semmle/python/frameworks/Yarl.qll @@ -0,0 +1,110 @@ +/** + * Provides classes modeling security-relevant aspects of the `yarl` PyPI package. + * See https://yarl.readthedocs.io/en/stable/. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.frameworks.Multidict + +/** + * INTERNAL: Do not use. + * + * Provides models for the `yarl` PyPI package. + * See https://multidict.readthedocs.io/en/stable/. + */ +module Yarl { + /** + * Provides models for a the `yarl.URL` class: + * + * See https://yarl.readthedocs.io/en/stable/api.html#yarl.URL + */ + module Url { + /** + * A source of instances of `yarl.URL`, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use `Url::instance()` predicate to get references to instances of `yarl.URL`. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + /** Gets a reference to an instance of `yarl.URL`. */ + private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of `yarl.URL`. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** + * Taint propagation for `yarl.URL`. + * + * See https://yarl.readthedocs.io/en/stable/api.html#yarl.URL + */ + class YarlUrlAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { + override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // Methods + // + // TODO: When we have tools that make it easy, model these properly to handle + // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach + // (since it allows us to at least capture the most common cases). + exists(DataFlow::AttrRead attr | + // methods (that replaces part of URL, taken as only arguments) + attr.getAttributeName() in [ + "with_scheme", "with_user", "with_password", "with_host", "with_port", "with_path", + "with_query", "with_query", "update_query", "update_query", "with_fragment", + "with_name", + // join is a bit different, but is still correct to add here :+1: + "join" + ] and + ( + // obj -> obj.meth() + nodeFrom = instance() and + attr.getObject() = nodeFrom and + nodeTo.(DataFlow::CallCfgNode).getFunction() = attr + or + // argument of obj.meth() -> obj.meth() + attr.getObject() = instance() and + nodeTo.(DataFlow::CallCfgNode).getFunction() = attr and + nodeFrom in [ + nodeTo.(DataFlow::CallCfgNode).getArg(_), + nodeTo.(DataFlow::CallCfgNode).getArgByName(_) + ] + ) + or + // other methods + nodeFrom = instance() and + attr.getObject() = nodeFrom and + attr.getAttributeName() in ["human_repr"] and + nodeTo.(DataFlow::CallCfgNode).getFunction() = attr + ) + or + // Attributes + nodeFrom = instance() and + nodeTo.(DataFlow::AttrRead).getObject() = nodeFrom and + nodeTo.(DataFlow::AttrRead).getAttributeName() in [ + "user", "raw_user", "password", "raw_password", "host", "raw_host", "port", + "explicit_port", "authority", "raw_authority", "path", "raw_path", "path_qs", + "raw_path_qs", "query_string", "raw_query_string", "fragment", "raw_fragment", "parts", + "raw_parts", "name", "raw_name", "query" + ] + } + } + + class YarlUrlMultiDictProxyInstance extends Multidict::MultiDictProxy::InstanceSource { + YarlUrlMultiDictProxyInstance() { + this.(DataFlow::AttrRead).getObject() = Yarl::Url::instance() and + this.(DataFlow::AttrRead).getAttributeName() = "query" + } + } + } +} diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index eab09f17e74..30e42cc3f3b 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -136,59 +136,60 @@ async def test_taint(request: web.Request): # $ requestHandler import yarl ensure_tainted( - request.url.user, # $ MISSING: tainted - request.url.raw_user, # $ MISSING: tainted + # see https://yarl.readthedocs.io/en/stable/api.html#yarl.URL + request.url.user, # $ tainted + request.url.raw_user, # $ tainted - request.url.password, # $ MISSING: tainted - request.url.raw_password, # $ MISSING: tainted + request.url.password, # $ tainted + request.url.raw_password, # $ tainted - request.url.host, # $ MISSING: tainted - request.url.raw_host, # $ MISSING: tainted + request.url.host, # $ tainted + request.url.raw_host, # $ tainted - request.url.port, # $ MISSING: tainted - request.url.explicit_port, # $ MISSING: tainted + request.url.port, # $ tainted + request.url.explicit_port, # $ tainted - request.url.authority, # $ MISSING: tainted - request.url.raw_authority, # $ MISSING: tainted + request.url.authority, # $ tainted + request.url.raw_authority, # $ tainted - request.url.path, # $ MISSING: tainted - request.url.raw_path, # $ MISSING: tainted + request.url.path, # $ tainted + request.url.raw_path, # $ tainted - request.url.path_qs, # $ MISSING: tainted - request.url.raw_path_qs, # $ MISSING: tainted + request.url.path_qs, # $ tainted + request.url.raw_path_qs, # $ tainted - request.url.query_string, # $ MISSING: tainted - request.url.raw_query_string, # $ MISSING: tainted + request.url.query_string, # $ tainted + request.url.raw_query_string, # $ tainted - request.url.fragment, # $ MISSING: tainted - request.url.raw_fragment, # $ MISSING: tainted + request.url.fragment, # $ tainted + request.url.raw_fragment, # $ tainted - request.url.parts, # $ MISSING: tainted - request.url.raw_parts, # $ MISSING: tainted + request.url.parts, # $ tainted + request.url.raw_parts, # $ tainted - request.url.name, # $ MISSING: tainted - request.url.raw_name, # $ MISSING: tainted + request.url.name, # $ tainted + request.url.raw_name, # $ tainted # multidict.MultiDictProxy[str] - request.url.query, # $ MISSING: tainted - request.url.query.getone("key"), # $ MISSING: tainted + request.url.query, # $ tainted + request.url.query.getone("key"), # $ tainted - request.url.with_scheme("foo"), # $ MISSING: tainted - request.url.with_user("foo"), # $ MISSING: tainted - request.url.with_password("foo"), # $ MISSING: tainted - request.url.with_host("foo"), # $ MISSING: tainted - request.url.with_port("foo"), # $ MISSING: tainted - request.url.with_path("foo"), # $ MISSING: tainted - request.url.with_query({"foo": 42}), # $ MISSING: tainted - request.url.with_query(foo=42), # $ MISSING: tainted - request.url.update_query({"foo": 42}), # $ MISSING: tainted - request.url.update_query(foo=42), # $ MISSING: tainted - request.url.with_fragment("foo"), # $ MISSING: tainted - request.url.with_name("foo"), # $ MISSING: tainted + request.url.with_scheme("foo"), # $ tainted + request.url.with_user("foo"), # $ tainted + request.url.with_password("foo"), # $ tainted + request.url.with_host("foo"), # $ tainted + request.url.with_port("foo"), # $ tainted + request.url.with_path("foo"), # $ tainted + request.url.with_query({"foo": 42}), # $ tainted + request.url.with_query(foo=42), # $ tainted + request.url.update_query({"foo": 42}), # $ tainted + request.url.update_query(foo=42), # $ tainted + request.url.with_fragment("foo"), # $ tainted + request.url.with_name("foo"), # $ tainted request.url.join(yarl.URL("wat.html")), # $ tainted - request.url.human_repr(), # $ MISSING: tainted + request.url.human_repr(), # $ tainted ) From 1aa222d7ccfafb8c7caaba18c00875325ffaf0db Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 1 Jun 2021 12:59:37 +0200 Subject: [PATCH 116/272] Python: Add taint-test for class-based view --- .../test/library-tests/frameworks/aiohttp/taint_test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 30e42cc3f3b..16d4fc27412 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -193,8 +193,16 @@ async def test_taint(request: web.Request): # $ requestHandler ) +class TaintTestClass(web.View): + def get(self): + ensure_tainted( + self.request, # $ MISSING: tainted + ) + + app = web.Application() app.router.add_get(r"/test_taint/{name}/{number:\d+}", test_taint) # $ routeSetup="/test_taint/{name}/{number:\d+}" +app.router.add_view(r"/test_taint_class", TaintTestClass) # $ routeSetup="/test_taint_class" if __name__ == "__main__": From 8c039d56881ea381d65e018faadb71b8b5d4b21f Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 1 Jun 2021 13:13:04 +0200 Subject: [PATCH 117/272] Python: Add more aiohttp view routing tests --- .../frameworks/aiohttp/routing_test.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py index 880a7f8cb87..ffd339a4d1a 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -109,6 +109,19 @@ if True: app.router.add_view("/MyWebView3", MyWebView3) # $ MISSING: routeSetup + # no route-setup + class MyWebViewNoRoute(web.View): + async def get(self): # $ MISSING: requestHandler + return web.Response(text="MyWebViewNoRoute.get") + + if len(__name__) < 0: # avoid running, but fool analysis to not consider dead code + # no explicit-view subclass (but route-setup) + class MyWebViewNoSubclassButRoute(somelib.someclass): + async def get(self): # $ MISSING: requestHandler + return web.Response(text="MyWebViewNoSubclassButRoute.get") + + app.router.add_view("/MyWebViewNoSubclassButRoute", MyWebViewNoSubclassButRoute) # $ MISSING: routeSetup + ## =================== ## ## "Routed parameters" ## ## =================== ## From c4b618dcf5d3b54a85208ffba9ba5c0a7ece0879 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 1 Jun 2021 17:21:41 +0200 Subject: [PATCH 118/272] Python: Model view-classes in aiohttp.web No taint modeling of them yet though --- .../src/semmle/python/frameworks/Aiohttp.qll | 150 +++++++++++++++++- .../frameworks/aiohttp/routing_test.py | 18 +-- .../frameworks/aiohttp/taint_test.py | 2 +- 3 files changed, 158 insertions(+), 12 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index c6616b93712..8ea5121d25c 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -20,6 +20,19 @@ private import semmle.python.frameworks.Yarl * See https://docs.aiohttp.org/en/stable/web.html */ module AiohttpWebModel { + /** + * Provides models for the `aiohttp.web.View` class and subclasses. + * + * See https://docs.aiohttp.org/en/stable/web_reference.html#view. + */ + module View { + /** Gets a reference to the `flask.views.View` class or any subclass. */ + API::Node subclassRef() { + result = API::moduleImport("aiohttp").getMember("web").getMember("View").getASubclass*() + } + } + + // -- route modeling -- /** Gets a reference to a `aiohttp.web.Application` instance. */ API::Node applicationInstance() { // Not sure whether you're allowed to add routes _after_ starting the app, for @@ -36,7 +49,6 @@ module AiohttpWebModel { result = applicationInstance().getMember("router") } - // -- route modeling -- /** A route setup in `aiohttp.web` */ abstract class AiohttpRouteSetup extends HTTP::Server::RouteSetup::Range { override Parameter getARoutedParameter() { none() } @@ -54,6 +66,50 @@ module AiohttpWebModel { } } + /** + * Gets a reference to a class, that has been backtracked from the view-class handler + * argument `origin` (to a route-setup for view-classes). + */ + private DataFlow::LocalSourceNode viewClassBackTracker( + DataFlow::TypeBackTracker t, DataFlow::Node origin + ) { + t.start() and + origin = any(AiohttpViewRouteSetup rs).getViewClassArg() and + result = origin.getALocalSource() + or + exists(DataFlow::TypeBackTracker t2 | + result = viewClassBackTracker(t2, origin).backtrack(t2, t) + ) + } + + /** + * Gets a reference to a class, that has been backtracked from the view-class handler + * argument `origin` (to a route-setup for view-classes). + */ + DataFlow::LocalSourceNode viewClassBackTracker(DataFlow::Node origin) { + result = viewClassBackTracker(DataFlow::TypeBackTracker::end(), origin) + } + + Class getBackTrackedViewClass(DataFlow::Node origin) { + result.getParent() = viewClassBackTracker(origin).asExpr() + } + + /** An aiohttp route setup that uses view-classes as request handlers. */ + abstract class AiohttpViewRouteSetup extends AiohttpRouteSetup { + /** Gets the argument specifying the view-class handler. */ + abstract DataFlow::Node getViewClassArg(); + + /** Gets the view-class that is referenced in the view-class handler argument. */ + Class getViewClass() { result = getBackTrackedViewClass(this.getViewClassArg()) } + + override Function getARequestHandler() { + exists(AiohttpViewClass cls | + cls = this.getViewClass() and + result = cls.getARequestHandler() + ) + } + } + /** * A route-setup from `add_route` or any of `add_get`, `add_post`, etc. on an * `aiohttp.web.UrlDispatcher`. @@ -142,6 +198,91 @@ module AiohttpWebModel { override Function getARequestHandler() { result.getADecorator() = this.asExpr() } } + /** + * A view-class route-setup from either: + * - `add_view` method on a `aiohttp.web.UrlDispatcher` + * - `view` function from `aiohttp.web` + */ + class AiohttpViewRouteSetupFromFunction extends AiohttpViewRouteSetup, DataFlow::CallCfgNode { + AiohttpViewRouteSetupFromFunction() { + this = urlDispathcerInstance().getMember("add_view").getACall() + or + this = API::moduleImport("aiohttp").getMember("web").getMember("view").getACall() + or + this = + API::moduleImport("aiohttp") + .getMember("web") + .getMember("RouteTableDef") + .getReturn() + .getMember("view") + .getACall() + } + + override DataFlow::Node getUrlPatternArg() { + result in [this.getArg(0), this.getArgByName("path")] + } + + override DataFlow::Node getViewClassArg() { + result in [this.getArg(1), this.getArgByName("handler")] + } + } + + /** + * A view-class route-setup from the `view` decorator from a `aiohttp.web.RouteTableDef`. + */ + class AiohttpViewRouteSetupFromDecorator extends AiohttpViewRouteSetup, DataFlow::CallCfgNode { + AiohttpViewRouteSetupFromDecorator() { + this = + API::moduleImport("aiohttp") + .getMember("web") + .getMember("RouteTableDef") + .getReturn() + .getMember("view") + .getACall() + } + + override DataFlow::Node getUrlPatternArg() { + result in [this.getArg(0), this.getArgByName("path")] + } + + override DataFlow::Node getViewClassArg() { none() } + + override Class getViewClass() { result.getADecorator() = this.asExpr() } + } + + /** A class that we consider a aiohttp.web View class. */ + abstract class AiohttpViewClass extends Class { + /** Gets a function that could handle incoming requests, if any. */ + Function getARequestHandler() { + // TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with + // points-to and `.lookup`, which would handle `post = my_post_handler` inside class def + result = this.getAMethod() and + result.getName() = HTTP::httpVerbLower() + } + } + + /** A class that has a super-type which is a aiohttp.web View class. */ + class AiohttpViewClassFromSuperClass extends AiohttpViewClass { + AiohttpViewClassFromSuperClass() { this.getABase() = View::subclassRef().getAUse().asExpr() } + } + + /** A class that is used in a route-setup, therefore being considered a aiohttp.web View class. */ + class AiohttpViewClassFromRouteSetup extends AiohttpViewClass { + AiohttpViewClassFromRouteSetup() { this = any(AiohttpViewRouteSetup rs).getViewClass() } + } + + /** A request handler defined in an `aiohttp.web` view class, that has no known route. */ + private class AiohttpViewClassRequestHandlerWithoutKnownRoute extends HTTP::Server::RequestHandler::Range { + AiohttpViewClassRequestHandlerWithoutKnownRoute() { + exists(AiohttpViewClass vc | vc.getARequestHandler() = this) and + not exists(AiohttpRouteSetup setup | setup.getARequestHandler() = this) + } + + override Parameter getARoutedParameter() { none() } + + override string getFramework() { result = "aiohttp.web" } + } + // --------------------------------------------------------------------------- // aiohttp.web.Request taint modeling // --------------------------------------------------------------------------- @@ -183,7 +324,7 @@ module AiohttpWebModel { DataFlow::ParameterNode { AiohttpRequestHandlerRequestParam() { exists(Function requestHandler | - requestHandler = any(AiohttpRouteSetup setup).getARequestHandler() and + requestHandler = any(AiohttpCoroutineRouteSetup setup).getARequestHandler() and // We select the _last_ parameter for the request since that is what they do in // `aiohttp-jinja2`. // https://github.com/aio-libs/aiohttp-jinja2/blob/7fb4daf2c3003921d34031d38c2311ee0e02c18b/aiohttp_jinja2/__init__.py#L235 @@ -200,6 +341,11 @@ module AiohttpWebModel { this.getParameter() = max(Parameter param, int i | param = requestHandler.getArg(i) | param order by i) ) + or + exists(AiohttpViewClass vc | + // TODO + none() + ) } override string getSourceType() { result = "aiohttp.web.Request" } diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py index ffd339a4d1a..934d7673718 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -83,20 +83,20 @@ if True: # `app.add_routes` with list class MyWebView1(web.View): - async def get(self): # $ MISSING: requestHandler + async def get(self): # $ requestHandler return web.Response(text="MyWebView1.get") app.add_routes([ - web.view("/MyWebView1", MyWebView1) # $ MISSING: routeSetup + web.view("/MyWebView1", MyWebView1) # $ routeSetup="/MyWebView1" ]) # using decorator routes = web.RouteTableDef() - @routes.view("/MyWebView2") # $ MISSING: routeSetup + @routes.view("/MyWebView2") # $ routeSetup="/MyWebView2" class MyWebView2(web.View): - async def get(self): # $ MISSING: requestHandler + async def get(self): # $ requestHandler return web.Response(text="MyWebView2.get") app.add_routes(routes) @@ -104,23 +104,23 @@ if True: # `app.router.add_view` class MyWebView3(web.View): - async def get(self): # $ MISSING: requestHandler + async def get(self): # $ requestHandler return web.Response(text="MyWebView3.get") - app.router.add_view("/MyWebView3", MyWebView3) # $ MISSING: routeSetup + app.router.add_view("/MyWebView3", MyWebView3) # $ routeSetup="/MyWebView3" # no route-setup class MyWebViewNoRoute(web.View): - async def get(self): # $ MISSING: requestHandler + async def get(self): # $ requestHandler return web.Response(text="MyWebViewNoRoute.get") if len(__name__) < 0: # avoid running, but fool analysis to not consider dead code # no explicit-view subclass (but route-setup) class MyWebViewNoSubclassButRoute(somelib.someclass): - async def get(self): # $ MISSING: requestHandler + async def get(self): # $ requestHandler return web.Response(text="MyWebViewNoSubclassButRoute.get") - app.router.add_view("/MyWebViewNoSubclassButRoute", MyWebViewNoSubclassButRoute) # $ MISSING: routeSetup + app.router.add_view("/MyWebViewNoSubclassButRoute", MyWebViewNoSubclassButRoute) # $ routeSetup="/MyWebViewNoSubclassButRoute" ## =================== ## ## "Routed parameters" ## diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 16d4fc27412..28ff33b15a6 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -194,7 +194,7 @@ async def test_taint(request: web.Request): # $ requestHandler class TaintTestClass(web.View): - def get(self): + def get(self): # $ requestHandler ensure_tainted( self.request, # $ MISSING: tainted ) From c69b85766261e64b47707f76ae1bf0dd0e3f6168 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 1 Jun 2021 17:32:56 +0200 Subject: [PATCH 119/272] Python: Add self.request as RemoteFlowSource for aiohttp View Just like we do for Django in https://github.com/github/codeql/blob/7393443f8ca0b51a55f2aa5cca9595ab35fb92dc/python/ql/src/semmle/python/frameworks/Django.qll#L1786-L1804 --- .../src/semmle/python/frameworks/Aiohttp.qll | 20 +++++++--- .../src/semmle/python/frameworks/Django.qll | 25 +----------- .../frameworks/internal/SelfRefMixin.qll | 38 +++++++++++++++++++ .../frameworks/aiohttp/taint_test.py | 3 +- 4 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 python/ql/src/semmle/python/frameworks/internal/SelfRefMixin.qll diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 8ea5121d25c..3a8989e2c4c 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -10,6 +10,7 @@ private import semmle.python.dataflow.new.TaintTracking private import semmle.python.Concepts private import semmle.python.ApiGraphs private import semmle.python.frameworks.internal.PoorMansFunctionResolution +private import semmle.python.frameworks.internal.SelfRefMixin private import semmle.python.frameworks.Multidict private import semmle.python.frameworks.Yarl @@ -251,7 +252,7 @@ module AiohttpWebModel { } /** A class that we consider a aiohttp.web View class. */ - abstract class AiohttpViewClass extends Class { + abstract class AiohttpViewClass extends Class, SelfRefMixin { /** Gets a function that could handle incoming requests, if any. */ Function getARequestHandler() { // TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with @@ -341,16 +342,23 @@ module AiohttpWebModel { this.getParameter() = max(Parameter param, int i | param = requestHandler.getArg(i) | param order by i) ) - or - exists(AiohttpViewClass vc | - // TODO - none() - ) } override string getSourceType() { result = "aiohttp.web.Request" } } + class AiohttpViewClassRequestAttributeRead extends Request::InstanceSource, + RemoteFlowSource::Range, DataFlow::Node { + AiohttpViewClassRequestAttributeRead() { + this.(DataFlow::AttrRead).getObject() = any(AiohttpViewClass vc).getASelfRef() and + this.(DataFlow::AttrRead).getAttributeName() = "request" + } + + override string getSourceType() { + result = "aiohttp.web.Request from self.request in View class" + } + } + /** * Taint propagation for `aiohttp.web.Request`. * diff --git a/python/ql/src/semmle/python/frameworks/Django.qll b/python/ql/src/semmle/python/frameworks/Django.qll index f1ae74bc8b5..fbe967d629f 100644 --- a/python/ql/src/semmle/python/frameworks/Django.qll +++ b/python/ql/src/semmle/python/frameworks/Django.qll @@ -12,6 +12,7 @@ private import semmle.python.ApiGraphs private import semmle.python.frameworks.PEP249 private import semmle.python.regex private import semmle.python.frameworks.internal.PoorMansFunctionResolution +private import semmle.python.frameworks.internal.SelfRefMixin /** * Provides models for the `django` PyPI package. @@ -1388,31 +1389,7 @@ private module PrivateDjango { // Helpers // --------------------------------------------------------------------------- - /** Adds the `getASelfRef` member predicate when modeling a class. */ - abstract private class SelfRefMixin extends Class { - /** - * Gets a reference to instances of this class, originating from a self parameter of - * a method defined on this class. - * - * Note: TODO: This doesn't take MRO into account - * Note: TODO: This doesn't take staticmethod/classmethod into account - */ - private DataFlow::LocalSourceNode getASelfRef(DataFlow::TypeTracker t) { - t.start() and - result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0) - or - exists(DataFlow::TypeTracker t2 | result = this.getASelfRef(t2).track(t2, t)) - } - /** - * Gets a reference to instances of this class, originating from a self parameter of - * a method defined on this class. - * - * Note: TODO: This doesn't take MRO into account - * Note: TODO: This doesn't take staticmethod/classmethod into account - */ - DataFlow::Node getASelfRef() { this.getASelfRef(DataFlow::TypeTracker::end()).flowsTo(result) } - } // --------------------------------------------------------------------------- // Form and form field modeling diff --git a/python/ql/src/semmle/python/frameworks/internal/SelfRefMixin.qll b/python/ql/src/semmle/python/frameworks/internal/SelfRefMixin.qll new file mode 100644 index 00000000000..d43d6b54bfb --- /dev/null +++ b/python/ql/src/semmle/python/frameworks/internal/SelfRefMixin.qll @@ -0,0 +1,38 @@ +/** + * INTERNAL: Do not use. + * + * Provides the `SelfRefMixin` class. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow + +/** + * INTERNAL: Do not use. + * + * Adds the `getASelfRef` member predicate when modeling a class. + */ +abstract class SelfRefMixin extends Class { + /** + * Gets a reference to instances of this class, originating from a self parameter of + * a method defined on this class. + * + * Note: TODO: This doesn't take MRO into account + * Note: TODO: This doesn't take staticmethod/classmethod into account + */ + private DataFlow::LocalSourceNode getASelfRef(DataFlow::TypeTracker t) { + t.start() and + result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0) + or + exists(DataFlow::TypeTracker t2 | result = this.getASelfRef(t2).track(t2, t)) + } + + /** + * Gets a reference to instances of this class, originating from a self parameter of + * a method defined on this class. + * + * Note: TODO: This doesn't take MRO into account + * Note: TODO: This doesn't take staticmethod/classmethod into account + */ + DataFlow::Node getASelfRef() { this.getASelfRef(DataFlow::TypeTracker::end()).flowsTo(result) } +} diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 28ff33b15a6..dcf21f92687 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -196,7 +196,8 @@ async def test_taint(request: web.Request): # $ requestHandler class TaintTestClass(web.View): def get(self): # $ requestHandler ensure_tainted( - self.request, # $ MISSING: tainted + self.request, # $ tainted + self.request.url # $ tainted ) From 919a0b6b84489488c1dcb1de41e0097f01ccddca Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 1 Jun 2021 17:51:19 +0200 Subject: [PATCH 120/272] Python: aiohttp route setup is more complicated than expected --- .../frameworks/aiohttp/routing_test.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py index 934d7673718..ad1883b5828 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -122,6 +122,23 @@ if True: app.router.add_view("/MyWebViewNoSubclassButRoute", MyWebViewNoSubclassButRoute) # $ routeSetup="/MyWebViewNoSubclassButRoute" + +# Apparently there is no enforcement that `add_view` is only for views, and vice-versa +# for `add_get` only being for async functions. +if True: + async def no_rules(request): # $ MISSING: requestHandler + return web.Response(text="no_rules") + + app.router.add_view("/no_rules", no_rules) # $ routeSetup="/no_rules" + + + class NoRulesView(web.View): + async def get(self): # $ requestHandler + return web.Response(text="NoRulesView.get") + + app.router.add_get("/NoRulesView", NoRulesView) # $ routeSetup="/NoRulesView" + + ## =================== ## ## "Routed parameters" ## ## =================== ## From 5d4140d3e2d26a81db5bdd859d97ca7b752425a1 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 1 Jun 2021 18:40:20 +0200 Subject: [PATCH 121/272] Python: Handle more complicated route-setup in aiohttp Since we want to be able to easy select request-handlers that are not set up as part of a view-class, we need to easily be able to identify those. To handle cases like the one below, we _can't_ just define these to be all the async functions that are not methods on a class :( ```py # see https://docs.aiohttp.org/en/stable/web_quickstart.html#organizing-handlers-in-classes class MyCustomHandlerClass: async def foo_handler(self, request): # $ MISSING: requestHandler return web.Response(text="MyCustomHandlerClass.foo") my_custom_handler = MyCustomHandlerClass() app.router.add_get("/MyCustomHandlerClass/foo", my_custom_handler.foo_handler) # $ routeSetup="/MyCustomHandlerClass/foo" ``` So it seemed easiest to narrow down the route-setups, but that means we want both refinement and extensibility... so `::Range` pattern to the rescue :tada: The important piece of code that still works after this commit, but which hasn't been changed, is the one below: ```codeql /** * A parameter that will receive a `aiohttp.web.Request` instance when a request * handler is invoked. */ class AiohttpRequestHandlerRequestParam extends Request::InstanceSource, RemoteFlowSource::Range, DataFlow::ParameterNode { AiohttpRequestHandlerRequestParam() { exists(Function requestHandler | requestHandler = any(AiohttpCoroutineRouteSetup setup).getARequestHandler() and ``` --- .../src/semmle/python/frameworks/Aiohttp.qll | 259 ++++++++---------- .../frameworks/aiohttp/routing_test.py | 2 +- 2 files changed, 121 insertions(+), 140 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index 3a8989e2c4c..f85071adaa2 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -50,110 +50,130 @@ module AiohttpWebModel { result = applicationInstance().getMember("router") } - /** A route setup in `aiohttp.web` */ - abstract class AiohttpRouteSetup extends HTTP::Server::RouteSetup::Range { + /** + * A route setup in `aiohttp.web`. Since all route-setups can technically use either + * coroutines or view-classes as the handler argument (although that's not how you're + * **supposed** to do things), we also need to handle this. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `AiohttpRouteSetup::Range` instead. + */ + class AiohttpRouteSetup extends HTTP::Server::RouteSetup::Range { + AiohttpRouteSetup::Range range; + + AiohttpRouteSetup() { this = range } + override Parameter getARoutedParameter() { none() } override string getFramework() { result = "aiohttp.web" } + + /** Gets the argument specifying the handler (either a coroutine or a view-class). */ + DataFlow::Node getHandlerArg() { result = range.getHandlerArg() } + + override DataFlow::Node getUrlPatternArg() { result = range.getUrlPatternArg() } + + /** Gets the view-class that is referenced in the view-class handler argument, if any. */ + Class getViewClass() { result = range.getViewClass() } + + override Function getARequestHandler() { result = range.getARequestHandler() } + } + + /** Provides a class for modeling new aiohttp.web route setups. */ + private module AiohttpRouteSetup { + /** + * A route setup in `aiohttp.web`. Since all route-setups can technically use either + * coroutines or view-classes as the handler argument (although that's not how you're + * **supposed** to do things), we also need to handle this. + * + * Extend this class to model new APIs. If you want to refine existing API models, + * extend `AiohttpRouteSetup` instead. + */ + abstract class Range extends DataFlow::Node { + /** Gets the argument used to set the URL pattern. */ + abstract DataFlow::Node getUrlPatternArg(); + + /** Gets the argument specifying the handler (either a coroutine or a view-class). */ + abstract DataFlow::Node getHandlerArg(); + + /** Gets the view-class that is referenced in the view-class handler argument, if any. */ + Class getViewClass() { result = getBackTrackedViewClass(this.getHandlerArg()) } + + /** + * Gets a function that will handle incoming requests for this route, if any. + * + * NOTE: This will be modified in the near future to have a `RequestHandler` result, instead of a `Function`. + */ + Function getARequestHandler() { + this.getHandlerArg() = poorMansFunctionTracker(result) + or + exists(AiohttpViewClass cls | + cls = this.getViewClass() and + result = cls.getARequestHandler() + ) + } + } + + /** + * Gets a reference to a class, that has been backtracked from the view-class handler + * argument `origin` (to a route-setup for view-classes). + */ + private DataFlow::LocalSourceNode viewClassBackTracker( + DataFlow::TypeBackTracker t, DataFlow::Node origin + ) { + t.start() and + origin = any(Range rs).getHandlerArg() and + result = origin.getALocalSource() + or + exists(DataFlow::TypeBackTracker t2 | + result = viewClassBackTracker(t2, origin).backtrack(t2, t) + ) + } + + /** + * Gets a reference to a class, that has been backtracked from the view-class handler + * argument `origin` (to a route-setup for view-classes). + */ + DataFlow::LocalSourceNode viewClassBackTracker(DataFlow::Node origin) { + result = viewClassBackTracker(DataFlow::TypeBackTracker::end(), origin) + } + + Class getBackTrackedViewClass(DataFlow::Node origin) { + result.getParent() = viewClassBackTracker(origin).asExpr() + } } /** An aiohttp route setup that uses coroutines (async function) as request handler. */ - abstract class AiohttpCoroutineRouteSetup extends AiohttpRouteSetup { - /** Gets the argument specifying the request handler (which is a coroutine/async function) */ - abstract DataFlow::Node getRequestHandlerArg(); - - override Function getARequestHandler() { - this.getRequestHandlerArg() = poorMansFunctionTracker(result) - } - } - - /** - * Gets a reference to a class, that has been backtracked from the view-class handler - * argument `origin` (to a route-setup for view-classes). - */ - private DataFlow::LocalSourceNode viewClassBackTracker( - DataFlow::TypeBackTracker t, DataFlow::Node origin - ) { - t.start() and - origin = any(AiohttpViewRouteSetup rs).getViewClassArg() and - result = origin.getALocalSource() - or - exists(DataFlow::TypeBackTracker t2 | - result = viewClassBackTracker(t2, origin).backtrack(t2, t) - ) - } - - /** - * Gets a reference to a class, that has been backtracked from the view-class handler - * argument `origin` (to a route-setup for view-classes). - */ - DataFlow::LocalSourceNode viewClassBackTracker(DataFlow::Node origin) { - result = viewClassBackTracker(DataFlow::TypeBackTracker::end(), origin) - } - - Class getBackTrackedViewClass(DataFlow::Node origin) { - result.getParent() = viewClassBackTracker(origin).asExpr() + class AiohttpCoroutineRouteSetup extends AiohttpRouteSetup { + AiohttpCoroutineRouteSetup() { this.getHandlerArg() = poorMansFunctionTracker(_) } } /** An aiohttp route setup that uses view-classes as request handlers. */ - abstract class AiohttpViewRouteSetup extends AiohttpRouteSetup { - /** Gets the argument specifying the view-class handler. */ - abstract DataFlow::Node getViewClassArg(); - - /** Gets the view-class that is referenced in the view-class handler argument. */ - Class getViewClass() { result = getBackTrackedViewClass(this.getViewClassArg()) } - - override Function getARequestHandler() { - exists(AiohttpViewClass cls | - cls = this.getViewClass() and - result = cls.getARequestHandler() - ) - } + class AiohttpViewRouteSetup extends AiohttpRouteSetup { + AiohttpViewRouteSetup() { exists(this.getViewClass()) } } /** - * A route-setup from `add_route` or any of `add_get`, `add_post`, etc. on an - * `aiohttp.web.UrlDispatcher`. + * A route-setup from + * - `add_route`, `add_view`, `add_get`, `add_post`, , etc. on an `aiohttp.web.UrlDispatcher`. + * - `route`, `view`, `get`, `post`, etc. functions from `aiohttp.web`. */ - class AiohttpUrlDispatcherAddRouteCall extends AiohttpCoroutineRouteSetup, DataFlow::CallCfgNode { + class AiohttpAddRouteCall extends AiohttpRouteSetup::Range, DataFlow::CallCfgNode { /** At what index route arguments starts, so we can handle "route" version together with get/post/... */ int routeArgsStart; - AiohttpUrlDispatcherAddRouteCall() { - this = urlDispathcerInstance().getMember("add_" + HTTP::httpVerbLower()).getACall() and - routeArgsStart = 0 - or - this = urlDispathcerInstance().getMember("add_route").getACall() and - routeArgsStart = 1 - } - - override DataFlow::Node getUrlPatternArg() { - result in [this.getArg(routeArgsStart + 0), this.getArgByName("path")] - } - - override DataFlow::Node getRequestHandlerArg() { - result in [this.getArg(routeArgsStart + 1), this.getArgByName("handler")] - } - } - - /** - * A route-setup from using `route` or any of `get`, `post`, etc. functions from `aiohttp.web`. - * - * Note that technically, this does not set up a route in itself (since it needs to be added to an application first). - * However, modeling this way makes it easier, and we don't expect it to lead to many problems. - */ - class AiohttpWebRouteCall extends AiohttpCoroutineRouteSetup, DataFlow::CallCfgNode { - /** At what index route arguments starts, so we can handle "route" version together with get/post/... */ - int routeArgsStart; - - AiohttpWebRouteCall() { + AiohttpAddRouteCall() { exists(string funcName | funcName = HTTP::httpVerbLower() and routeArgsStart = 0 or + funcName = "view" and + routeArgsStart = 0 + or funcName = "route" and routeArgsStart = 1 | + this = urlDispathcerInstance().getMember("add_" + funcName).getACall() + or this = API::moduleImport("aiohttp").getMember("web").getMember(funcName).getACall() ) } @@ -162,21 +182,24 @@ module AiohttpWebModel { result in [this.getArg(routeArgsStart + 0), this.getArgByName("path")] } - override DataFlow::Node getRequestHandlerArg() { + override DataFlow::Node getHandlerArg() { result in [this.getArg(routeArgsStart + 1), this.getArgByName("handler")] } } - /** A route-setup from using a `route` or any of `get`, `post`, etc. decorators from a `aiohttp.web.RouteTableDef`. */ - class AiohttpRouteTableDefRouteCall extends AiohttpCoroutineRouteSetup, DataFlow::CallCfgNode { + /** A route-setup using a decorator, such as `route`, `view`, `get`, `post`, etc. on a `aiohttp.web.RouteTableDef`. */ + class AiohttpDecoratorRouteSetup extends AiohttpRouteSetup::Range, DataFlow::CallCfgNode { /** At what index route arguments starts, so we can handle "route" version together with get/post/... */ int routeArgsStart; - AiohttpRouteTableDefRouteCall() { + AiohttpDecoratorRouteSetup() { exists(string decoratorName | decoratorName = HTTP::httpVerbLower() and routeArgsStart = 0 or + decoratorName = "view" and + routeArgsStart = 0 + or decoratorName = "route" and routeArgsStart = 1 | @@ -194,61 +217,19 @@ module AiohttpWebModel { result in [this.getArg(routeArgsStart + 0), this.getArgByName("path")] } - override DataFlow::Node getRequestHandlerArg() { none() } - - override Function getARequestHandler() { result.getADecorator() = this.asExpr() } - } - - /** - * A view-class route-setup from either: - * - `add_view` method on a `aiohttp.web.UrlDispatcher` - * - `view` function from `aiohttp.web` - */ - class AiohttpViewRouteSetupFromFunction extends AiohttpViewRouteSetup, DataFlow::CallCfgNode { - AiohttpViewRouteSetupFromFunction() { - this = urlDispathcerInstance().getMember("add_view").getACall() - or - this = API::moduleImport("aiohttp").getMember("web").getMember("view").getACall() - or - this = - API::moduleImport("aiohttp") - .getMember("web") - .getMember("RouteTableDef") - .getReturn() - .getMember("view") - .getACall() - } - - override DataFlow::Node getUrlPatternArg() { - result in [this.getArg(0), this.getArgByName("path")] - } - - override DataFlow::Node getViewClassArg() { - result in [this.getArg(1), this.getArgByName("handler")] - } - } - - /** - * A view-class route-setup from the `view` decorator from a `aiohttp.web.RouteTableDef`. - */ - class AiohttpViewRouteSetupFromDecorator extends AiohttpViewRouteSetup, DataFlow::CallCfgNode { - AiohttpViewRouteSetupFromDecorator() { - this = - API::moduleImport("aiohttp") - .getMember("web") - .getMember("RouteTableDef") - .getReturn() - .getMember("view") - .getACall() - } - - override DataFlow::Node getUrlPatternArg() { - result in [this.getArg(0), this.getArgByName("path")] - } - - override DataFlow::Node getViewClassArg() { none() } + override DataFlow::Node getHandlerArg() { none() } override Class getViewClass() { result.getADecorator() = this.asExpr() } + + override Function getARequestHandler() { + // we're decorating a class + exists(this.getViewClass()) and + result = super.getARequestHandler() + or + // we're decorating a function + not exists(this.getViewClass()) and + result.getADecorator() = this.asExpr() + } } /** A class that we consider a aiohttp.web View class. */ @@ -269,7 +250,7 @@ module AiohttpWebModel { /** A class that is used in a route-setup, therefore being considered a aiohttp.web View class. */ class AiohttpViewClassFromRouteSetup extends AiohttpViewClass { - AiohttpViewClassFromRouteSetup() { this = any(AiohttpViewRouteSetup rs).getViewClass() } + AiohttpViewClassFromRouteSetup() { this = any(AiohttpRouteSetup rs).getViewClass() } } /** A request handler defined in an `aiohttp.web` view class, that has no known route. */ diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py index ad1883b5828..eac030ec02a 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -126,7 +126,7 @@ if True: # Apparently there is no enforcement that `add_view` is only for views, and vice-versa # for `add_get` only being for async functions. if True: - async def no_rules(request): # $ MISSING: requestHandler + async def no_rules(request): # $ requestHandler return web.Response(text="no_rules") app.router.add_view("/no_rules", no_rules) # $ routeSetup="/no_rules" From 735df4597f7563528062cf5eb6579ad12680a2a5 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 2 Jun 2021 10:58:04 +0200 Subject: [PATCH 122/272] Python: Aiohttp add response tests --- .../frameworks/aiohttp/response_test.py | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/aiohttp/response_test.py b/python/ql/test/library-tests/frameworks/aiohttp/response_test.py index e69de29bb2d..e58d0c6c189 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/response_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/response_test.py @@ -0,0 +1,72 @@ +from aiohttp import web + + +routes = web.RouteTableDef() + + +@routes.get("/raw_text") # $ routeSetup="/raw_text" +async def raw_text(request): # $ requestHandler + return web.Response(text="foo") # $ MISSING: HttpResponse + + +@routes.get("/raw_body") # $ routeSetup="/raw_body" +async def raw_body(request): # $ requestHandler + return web.Response(body=b"foo") # $ MISSING: HttpResponse + + +@routes.get("/html_text") # $ routeSetup="/html_text" +async def html_text(request): # $ requestHandler + return web.Response(text="foo", content_type="text/html") # $ MISSING: HttpResponse + + +@routes.get("/html_body") # $ routeSetup="/html_body" +async def html_body(request): # $ requestHandler + return web.Response(body=b"foo", content_type="text/html") # $ MISSING: HttpResponse + + +@routes.get("/html_body_set_later") # $ routeSetup="/html_body_set_later" +async def html_body_set_later(request): # $ requestHandler + resp = web.Response(body=b"foo") # $ MISSING: HttpResponse + resp.content_type = "text/html" + return resp + +# Each HTTP status code has an exception +# see https://docs.aiohttp.org/en/stable/web_quickstart.html#exceptions + +@routes.get("/through_200_exception") # $ routeSetup="/through_200_exception" +async def through_200_exception(request): # $ requestHandler + raise web.HTTPOk(text="foo") # $ MISSING: HttpResponse + + +@routes.get("/through_200_exception_html") # $ routeSetup="/through_200_exception_html" +async def through_200_exception(request): # $ requestHandler + exception = web.HTTPOk(text="foo") # $ MISSING: HttpResponse + exception.content_type = "text/html" + raise exception + + +@routes.get("/through_404_exception") # $ routeSetup="/through_404_exception" +async def through_404_exception(request): # $ requestHandler + raise web.HTTPNotFound(text="foo") # $ MISSING: HttpResponse + + +@routes.get("/redirect_301") # $ routeSetup="/redirect_301" +async def redirect_301(request): # $ requestHandler + if not "kwarg" in request.url.query: + raise web.HTTPMovedPermanently("/login") # $ MISSING: HttpResponse HttpRedirectResponse + else: + raise web.HTTPMovedPermanently(location="/logout") # $ MISSING: HttpResponse HttpRedirectResponse + + +@routes.get("/redirect_302") # $ routeSetup="/redirect_302" +async def redirect_302(request): # $ requestHandler + if not "kwarg" in request.url.query: + raise web.HTTPFound("/login") # $ MISSING: HttpResponse HttpRedirectResponse + else: + raise web.HTTPFound(location="/logout") # $ MISSING: HttpResponse HttpRedirectResponse + + +if __name__ == "__main__": + app = web.Application() + app.add_routes(routes) + web.run_app(app) From 2dbbf52903bd32439c337f7e31c52313aa6f49ff Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 2 Jun 2021 18:08:13 +0200 Subject: [PATCH 123/272] Python: Model HTTP responses in aiohttp.web --- .../src/semmle/python/frameworks/Aiohttp.qll | 85 +++++++++++++++++++ .../frameworks/aiohttp/response_test.py | 28 +++--- .../frameworks/aiohttp/routing_test.py | 40 ++++----- 3 files changed, 119 insertions(+), 34 deletions(-) diff --git a/python/ql/src/semmle/python/frameworks/Aiohttp.qll b/python/ql/src/semmle/python/frameworks/Aiohttp.qll index f85071adaa2..24f141807ba 100644 --- a/python/ql/src/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/src/semmle/python/frameworks/Aiohttp.qll @@ -391,4 +391,89 @@ module AiohttpWebModel { this.(DataFlow::AttrRead).getAttributeName() in ["url", "rel_url"] } } + + // --------------------------------------------------------------------------- + // aiohttp.web Response modeling + // --------------------------------------------------------------------------- + /** + * An instantiation of `aiohttp.web.Response`. + * + * Note that `aiohttp.web.HTTPException` (and it's subclasses) is a subclass of `aiohttp.web.Response`. + * + * See + * - https://docs.aiohttp.org/en/stable/web_reference.html#aiohttp.web.Response + * - https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-web-exceptions + */ + class AiohttpWebResponseInstantiation extends HTTP::Server::HttpResponse::Range, + DataFlow::CallCfgNode { + AiohttpWebResponseInstantiation() { + this = API::moduleImport("aiohttp").getMember("web").getMember("Response").getACall() + or + exists(string httpExceptionClassName | + httpExceptionClassName in [ + "HTTPException", "HTTPSuccessful", "HTTPOk", "HTTPCreated", "HTTPAccepted", + "HTTPNonAuthoritativeInformation", "HTTPNoContent", "HTTPResetContent", + "HTTPPartialContent", "HTTPRedirection", "HTTPMultipleChoices", "HTTPMovedPermanently", + "HTTPFound", "HTTPSeeOther", "HTTPNotModified", "HTTPUseProxy", "HTTPTemporaryRedirect", + "HTTPPermanentRedirect", "HTTPError", "HTTPClientError", "HTTPBadRequest", + "HTTPUnauthorized", "HTTPPaymentRequired", "HTTPForbidden", "HTTPNotFound", + "HTTPMethodNotAllowed", "HTTPNotAcceptable", "HTTPProxyAuthenticationRequired", + "HTTPRequestTimeout", "HTTPConflict", "HTTPGone", "HTTPLengthRequired", + "HTTPPreconditionFailed", "HTTPRequestEntityTooLarge", "HTTPRequestURITooLong", + "HTTPUnsupportedMediaType", "HTTPRequestRangeNotSatisfiable", "HTTPExpectationFailed", + "HTTPMisdirectedRequest", "HTTPUnprocessableEntity", "HTTPFailedDependency", + "HTTPUpgradeRequired", "HTTPPreconditionRequired", "HTTPTooManyRequests", + "HTTPRequestHeaderFieldsTooLarge", "HTTPUnavailableForLegalReasons", "HTTPServerError", + "HTTPInternalServerError", "HTTPNotImplemented", "HTTPBadGateway", + "HTTPServiceUnavailable", "HTTPGatewayTimeout", "HTTPVersionNotSupported", + "HTTPVariantAlsoNegotiates", "HTTPInsufficientStorage", "HTTPNotExtended", + "HTTPNetworkAuthenticationRequired" + ] and + this = + API::moduleImport("aiohttp").getMember("web").getMember(httpExceptionClassName).getACall() + ) + } + + override DataFlow::Node getBody() { + result in [this.getArgByName("text"), this.getArgByName("body")] + } + + override DataFlow::Node getMimetypeOrContentTypeArg() { + result = this.getArgByName("content_type") + } + + override string getMimetypeDefault() { + exists(this.getArgByName("text")) and + result = "text/plain" + or + not exists(this.getArgByName("text")) and + result = "application/octet-stream" + } + } + + /** + * An instantiation of aiohttp.web HTTP redirect exception. + * + * See the part about redirects at https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-web-exceptions + */ + class AiohttpRedirectExceptionInstantiation extends AiohttpWebResponseInstantiation, + HTTP::Server::HttpRedirectResponse::Range { + AiohttpRedirectExceptionInstantiation() { + exists(string httpRedirectExceptionClassName | + httpRedirectExceptionClassName in [ + "HTTPMultipleChoices", "HTTPMovedPermanently", "HTTPFound", "HTTPSeeOther", + "HTTPNotModified", "HTTPUseProxy", "HTTPTemporaryRedirect", "HTTPPermanentRedirect" + ] and + this = + API::moduleImport("aiohttp") + .getMember("web") + .getMember(httpRedirectExceptionClassName) + .getACall() + ) + } + + override DataFlow::Node getRedirectLocation() { + result in [this.getArg(0), this.getArgByName("location")] + } + } } diff --git a/python/ql/test/library-tests/frameworks/aiohttp/response_test.py b/python/ql/test/library-tests/frameworks/aiohttp/response_test.py index e58d0c6c189..1988f443560 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/response_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/response_test.py @@ -6,28 +6,28 @@ routes = web.RouteTableDef() @routes.get("/raw_text") # $ routeSetup="/raw_text" async def raw_text(request): # $ requestHandler - return web.Response(text="foo") # $ MISSING: HttpResponse + return web.Response(text="foo") # $ HttpResponse mimetype=text/plain responseBody="foo" @routes.get("/raw_body") # $ routeSetup="/raw_body" async def raw_body(request): # $ requestHandler - return web.Response(body=b"foo") # $ MISSING: HttpResponse + return web.Response(body=b"foo") # $ HttpResponse mimetype=application/octet-stream responseBody=b"foo" @routes.get("/html_text") # $ routeSetup="/html_text" async def html_text(request): # $ requestHandler - return web.Response(text="foo", content_type="text/html") # $ MISSING: HttpResponse + return web.Response(text="foo", content_type="text/html") # $ HttpResponse mimetype=text/html responseBody="foo" @routes.get("/html_body") # $ routeSetup="/html_body" async def html_body(request): # $ requestHandler - return web.Response(body=b"foo", content_type="text/html") # $ MISSING: HttpResponse + return web.Response(body=b"foo", content_type="text/html") # $ HttpResponse mimetype=text/html responseBody=b"foo" @routes.get("/html_body_set_later") # $ routeSetup="/html_body_set_later" async def html_body_set_later(request): # $ requestHandler - resp = web.Response(body=b"foo") # $ MISSING: HttpResponse - resp.content_type = "text/html" + resp = web.Response(body=b"foo") # $ HttpResponse mimetype=application/octet-stream responseBody=b"foo" + resp.content_type = "text/html" # $ MISSING: mimetype=text/html return resp # Each HTTP status code has an exception @@ -35,35 +35,35 @@ async def html_body_set_later(request): # $ requestHandler @routes.get("/through_200_exception") # $ routeSetup="/through_200_exception" async def through_200_exception(request): # $ requestHandler - raise web.HTTPOk(text="foo") # $ MISSING: HttpResponse + raise web.HTTPOk(text="foo") # $ HttpResponse mimetype=text/plain responseBody="foo" @routes.get("/through_200_exception_html") # $ routeSetup="/through_200_exception_html" async def through_200_exception(request): # $ requestHandler - exception = web.HTTPOk(text="foo") # $ MISSING: HttpResponse - exception.content_type = "text/html" + exception = web.HTTPOk(text="foo") # $ HttpResponse mimetype=text/plain responseBody="foo" + exception.content_type = "text/html" # $ MISSING: mimetype=text/html raise exception @routes.get("/through_404_exception") # $ routeSetup="/through_404_exception" async def through_404_exception(request): # $ requestHandler - raise web.HTTPNotFound(text="foo") # $ MISSING: HttpResponse + raise web.HTTPNotFound(text="foo") # $ HttpResponse mimetype=text/plain responseBody="foo" @routes.get("/redirect_301") # $ routeSetup="/redirect_301" async def redirect_301(request): # $ requestHandler if not "kwarg" in request.url.query: - raise web.HTTPMovedPermanently("/login") # $ MISSING: HttpResponse HttpRedirectResponse + raise web.HTTPMovedPermanently("/login") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/login" else: - raise web.HTTPMovedPermanently(location="/logout") # $ MISSING: HttpResponse HttpRedirectResponse + raise web.HTTPMovedPermanently(location="/logout") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/logout" @routes.get("/redirect_302") # $ routeSetup="/redirect_302" async def redirect_302(request): # $ requestHandler if not "kwarg" in request.url.query: - raise web.HTTPFound("/login") # $ MISSING: HttpResponse HttpRedirectResponse + raise web.HTTPFound("/login") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/login" else: - raise web.HTTPFound(location="/logout") # $ MISSING: HttpResponse HttpRedirectResponse + raise web.HTTPFound(location="/logout") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/logout" if __name__ == "__main__": diff --git a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py index eac030ec02a..23bd9c93a3c 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/routing_test.py @@ -16,13 +16,13 @@ if True: # `app.add_routes` with list async def foo(request): # $ requestHandler - return web.Response(text="foo") + return web.Response(text="foo") # $ HttpResponse async def foo2(request): # $ requestHandler - return web.Response(text="foo2") + return web.Response(text="foo2") # $ HttpResponse async def foo3(request): # $ requestHandler - return web.Response(text="foo3") + return web.Response(text="foo3") # $ HttpResponse app.add_routes([ web.get("/foo", foo), # $ routeSetup="/foo" @@ -36,32 +36,32 @@ if True: @routes.get("/bar") # $ routeSetup="/bar" async def bar(request): # $ requestHandler - return web.Response(text="bar") + return web.Response(text="bar") # $ HttpResponse @routes.route("*", "/bar2") # $ routeSetup="/bar2" async def bar2(request): # $ requestHandler - return web.Response(text="bar2") + return web.Response(text="bar2") # $ HttpResponse @routes.get(path="/bar3") # $ routeSetup="/bar3" async def bar3(request): # $ requestHandler - return web.Response(text="bar3") + return web.Response(text="bar3") # $ HttpResponse app.add_routes(routes) # `app.router.add_get` / `app.router.add_route` async def baz(request): # $ requestHandler - return web.Response(text="baz") + return web.Response(text="baz") # $ HttpResponse app.router.add_get("/baz", baz) # $ routeSetup="/baz" async def baz2(request): # $ requestHandler - return web.Response(text="baz2") + return web.Response(text="baz2") # $ HttpResponse app.router.add_route("*", "/baz2", baz2) # $ routeSetup="/baz2" async def baz3(request): # $ requestHandler - return web.Response(text="baz3") + return web.Response(text="baz3") # $ HttpResponse app.router.add_get(path="/baz3", handler=baz3) # $ routeSetup="/baz3" @@ -73,7 +73,7 @@ if True: class MyCustomHandlerClass: async def foo_handler(self, request): # $ MISSING: requestHandler - return web.Response(text="MyCustomHandlerClass.foo") + return web.Response(text="MyCustomHandlerClass.foo") # $ HttpResponse my_custom_handler = MyCustomHandlerClass() app.router.add_get("/MyCustomHandlerClass/foo", my_custom_handler.foo_handler) # $ routeSetup="/MyCustomHandlerClass/foo" @@ -84,7 +84,7 @@ if True: # `app.add_routes` with list class MyWebView1(web.View): async def get(self): # $ requestHandler - return web.Response(text="MyWebView1.get") + return web.Response(text="MyWebView1.get") # $ HttpResponse app.add_routes([ web.view("/MyWebView1", MyWebView1) # $ routeSetup="/MyWebView1" @@ -97,7 +97,7 @@ if True: @routes.view("/MyWebView2") # $ routeSetup="/MyWebView2" class MyWebView2(web.View): async def get(self): # $ requestHandler - return web.Response(text="MyWebView2.get") + return web.Response(text="MyWebView2.get") # $ HttpResponse app.add_routes(routes) @@ -105,20 +105,20 @@ if True: # `app.router.add_view` class MyWebView3(web.View): async def get(self): # $ requestHandler - return web.Response(text="MyWebView3.get") + return web.Response(text="MyWebView3.get") # $ HttpResponse app.router.add_view("/MyWebView3", MyWebView3) # $ routeSetup="/MyWebView3" # no route-setup class MyWebViewNoRoute(web.View): async def get(self): # $ requestHandler - return web.Response(text="MyWebViewNoRoute.get") + return web.Response(text="MyWebViewNoRoute.get") # $ HttpResponse if len(__name__) < 0: # avoid running, but fool analysis to not consider dead code # no explicit-view subclass (but route-setup) class MyWebViewNoSubclassButRoute(somelib.someclass): async def get(self): # $ requestHandler - return web.Response(text="MyWebViewNoSubclassButRoute.get") + return web.Response(text="MyWebViewNoSubclassButRoute.get") # $ HttpResponse app.router.add_view("/MyWebViewNoSubclassButRoute", MyWebViewNoSubclassButRoute) # $ routeSetup="/MyWebViewNoSubclassButRoute" @@ -127,14 +127,14 @@ if True: # for `add_get` only being for async functions. if True: async def no_rules(request): # $ requestHandler - return web.Response(text="no_rules") + return web.Response(text="no_rules") # $ HttpResponse app.router.add_view("/no_rules", no_rules) # $ routeSetup="/no_rules" class NoRulesView(web.View): async def get(self): # $ requestHandler - return web.Response(text="NoRulesView.get") + return web.Response(text="NoRulesView.get") # $ HttpResponse app.router.add_get("/NoRulesView", NoRulesView) # $ routeSetup="/NoRulesView" @@ -149,7 +149,7 @@ if True: async def matching(request: web.Request): # $ requestHandler name = request.match_info['name'] number = request.match_info['number'] - return web.Response(text="matching name={} number={}".format(name, number)) + return web.Response(text="matching name={} number={}".format(name, number)) # $ HttpResponse app.router.add_get(r"/matching/{name}/{number:\d+}", matching) # $ routeSetup="/matching/{name}/{number:\d+}" @@ -161,7 +161,7 @@ if True: subapp = web.Application() async def subapp_handler(request): # $ requestHandler - return web.Response(text="subapp_handler") + return web.Response(text="subapp_handler") # $ HttpResponse subapp.router.add_get("/subapp_handler", subapp_handler) # $ routeSetup="/subapp_handler" @@ -177,7 +177,7 @@ if True: if True: async def manual_dispatcher_instance(request): # $ requestHandler - return web.Response(text="manual_dispatcher_instance") + return web.Response(text="manual_dispatcher_instance") # $ HttpResponse url_dispatcher = web.UrlDispatcher() url_dispatcher.add_get("/manual_dispatcher_instance", manual_dispatcher_instance) # $ routeSetup="/manual_dispatcher_instance" From 3c47e583d82911967103f13148f6ece78ded09bb Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 3 Jun 2021 10:54:36 +0200 Subject: [PATCH 124/272] Python: Add test for missing data-flow step in aiohttp.web --- .../frameworks/aiohttp/app_conf_test.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 python/ql/test/library-tests/frameworks/aiohttp/app_conf_test.py diff --git a/python/ql/test/library-tests/frameworks/aiohttp/app_conf_test.py b/python/ql/test/library-tests/frameworks/aiohttp/app_conf_test.py new file mode 100644 index 00000000000..ce15e2110ab --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiohttp/app_conf_test.py @@ -0,0 +1,48 @@ +""" +This file is a test of an extra data-flow step that we want to have for +aiohttp.web.Application + +We don't really have an established way to test extra data-flow steps in external +libraries right now, so for now I've just used our normal taint-flow testing ¯\_(ツ)_/¯ + +see https://docs.aiohttp.org/en/stable/web_advanced.html#application-s-config +""" + +from aiohttp import web + +# to make code runable +TAINTED_STRING = "TAINTED_STRING" +def ensure_tainted(*args, **kwargs): + pass + +ensure_tainted( + TAINTED_STRING # $ tainted +) + + +async def example(request: web.Request): # $ requestHandler + return web.Response(text=f'example {request.app["foo"]=}') # $ HttpResponse + + +async def also_works(request: web.Request): # $ requestHandler + return web.Response(text=f'also_works {request.config_dict["foo"]=}') # $ HttpResponse + + +async def taint_test(request: web.Request): # $ requestHandler + ensure_tainted( + request.app["ts"], # $ MISSING: tainted + request.config_dict["ts"], # $ MISSING: tainted + ) + return web.Response(text="ok") # $ HttpResponse + + +app = web.Application() +app.router.add_get("", example) # $ routeSetup="" +app.router.add_get("/also-works", also_works) # $ routeSetup="/also-works" +app.router.add_get("/taint-test", taint_test) # $ routeSetup="/taint-test" +app["foo"] = 42 +app["ts"] = TAINTED_STRING + + +if __name__ == "__main__": + web.run_app(app) From 607dcd4a277776fcf91405b13b0cf24dbeaf2735 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 3 Jun 2021 11:05:13 +0200 Subject: [PATCH 125/272] Don't use CSV models for private flow configs --- .../code/java/security/JexlInjection.qll | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/java/ql/src/semmle/code/java/security/JexlInjection.qll b/java/ql/src/semmle/code/java/security/JexlInjection.qll index 8e8923a746b..2328a4d4cbb 100644 --- a/java/ql/src/semmle/code/java/security/JexlInjection.qll +++ b/java/ql/src/semmle/code/java/security/JexlInjection.qll @@ -131,43 +131,40 @@ private predicate isSafeEngine(Expr expr) { private class SandboxedJexlFlowConfig extends DataFlow2::Configuration { SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" } - override predicate isSource(DataFlow::Node node) { sourceNode(node, "sandboxed-jexl") } + override predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource } - override predicate isSink(DataFlow::Node node) { sinkNode(node, "sandboxed-jexl") } + override predicate isSink(DataFlow::Node node) { + exists(MethodAccess ma, Method m | + m instanceof CreateJexlScriptMethod or + m instanceof CreateJexlExpressionMethod or + m instanceof CreateJexlTemplateMethod + | + ma.getMethod() = m and ma.getQualifier() = node.asExpr() + ) + } override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { createJexlEngineStep(fromNode, toNode) } } -private class SandoboxedJexlSourceModel extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // JEXL2 - "org.apache.commons.jexl2;JexlEngine;false;JexlEngine;(Uberspect,JexlArithmetic,Map,Log);;ReturnValue;sandboxed-jexl", - // JEXL3 - "org.apache.commons.jexl3;JexlBuilder;false;uberspect;(JexlUberspect);;ReturnValue;sandboxed-jexl", - "org.apache.commons.jexl3;JexlBuilder;false;sandbox;(JexlSandbox);;ReturnValue;sandboxed-jexl" - ] - } -} - -private class SandoboxedJexlSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // JEXL2 - "org.apache.commons.jexl2;JexlEngine;false;createScript;;;Argument[-1];sandboxed-jexl", - "org.apache.commons.jexl2;JexlEngine;false;createExpression;;;Argument[-1];sandboxed-jexl", - "org.apache.commons.jexl2;UnifiedJEXL;false;parse;;;Argument[-1];sandboxed-jexl", - "org.apache.commons.jexl2;UnifiedJEXL;false;createTemplate;;;Argument[-1];sandboxed-jexl", - // JEXL3 - "org.apache.commons.jexl3;JexlEngine;false;createScript;;;Argument[-1];sandboxed-jexl", - "org.apache.commons.jexl3;JexlEngine;false;createExpression;;;Argument[-1];sandboxed-jexl", - "org.apache.commons.jexl3;JxltEngine;false;createExpression;;;Argument[-1];sandboxed-jexl", - "org.apache.commons.jexl3;JxltEngine;false;createTemplate;;;Argument[-1];sandboxed-jexl" - ] +/** + * Defines a data flow source for JEXL engines configured with a sandbox. + */ +private class SandboxedJexlSource extends DataFlow::ExprNode { + SandboxedJexlSource() { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + m.getDeclaringType() instanceof JexlBuilder and + m.hasName(["uberspect", "sandbox"]) and + m.getReturnType() instanceof JexlBuilder and + this.asExpr() = [ma, ma.getQualifier()] + ) + or + exists(ConstructorCall cc | + cc.getConstructedType() instanceof JexlEngine and + cc.getArgument(0).getType() instanceof JexlUberspect and + cc = this.asExpr() + ) } } @@ -238,6 +235,13 @@ private class UnifiedJexl extends JexlRefType { UnifiedJexl() { hasName("UnifiedJEXL") } } +private class JexlUberspect extends Interface { + JexlUberspect() { + hasQualifiedName("org.apache.commons.jexl2.introspection", "Uberspect") or + hasQualifiedName("org.apache.commons.jexl3.introspection", "JexlUberspect") + } +} + private class Reader extends RefType { Reader() { hasQualifiedName("java.io", "Reader") } } From d044b155338fa184f3069a5e943e6273776f96f5 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 3 Jun 2021 10:54:45 +0200 Subject: [PATCH 126/272] C#: Add colliding method ID tests --- .../library-tests/methods/DB-CHECK.expected | 130 +++ .../methods/ExtensionMethods.expected | 24 +- .../library-tests/methods/Methods1.expected | 2 +- .../library-tests/methods/Methods2.expected | 2 +- .../library-tests/methods/Methods3.expected | 2 +- .../library-tests/methods/Methods4.expected | 2 +- .../library-tests/methods/Methods5.expected | 52 +- .../methods/Parameters1.expected | 4 +- .../methods/Parameters2.expected | 8 +- .../methods/Parameters3.expected | 4 +- .../methods/Parameters5.expected | 14 +- .../methods/Parameters6.expected | 4 +- .../methods/Parameters7.expected | 2 +- .../methods/Parameters8.expected | 102 +- .../methods/Parameters9.expected | 14 +- .../library-tests/methods/PrintAst.expected | 931 ++++++++++-------- .../ql/test/library-tests/methods/methods.cs | 28 + 17 files changed, 798 insertions(+), 527 deletions(-) create mode 100644 csharp/ql/test/library-tests/methods/DB-CHECK.expected diff --git a/csharp/ql/test/library-tests/methods/DB-CHECK.expected b/csharp/ql/test/library-tests/methods/DB-CHECK.expected new file mode 100644 index 00000000000..4a99289a434 --- /dev/null +++ b/csharp/ql/test/library-tests/methods/DB-CHECK.expected @@ -0,0 +1,130 @@ +[INVALID_KEY] predicate methods(@method id, string name, @type declaring_type_id, @type_or_ref type_id, @method unbound_id): The key set {id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 4: +Tuple 1 in row 28: (828,"M",827,1087,813) +Tuple 2 in row 29: (828,"M",827,1087,1135) + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 827: @"(294)<(366)>;type". The ID may expand to @"{@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"{@";namespace"}.System;namespace"}.Int32;type"}>;type" + Relevant element: Full ID for 1087: @"(365);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"};typeRef" + Relevant element: Full ID for 813: @"(365) (294).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 827: @"(294)<(366)>;type". The ID may expand to @"{@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"{@";namespace"}.System;namespace"}.Int32;type"}>;type" + Relevant element: Full ID for 1087: @"(365);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"};typeRef" + Relevant element: Full ID for 1135: @"(365) (294).M((296) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" +[INVALID_KEY] predicate constructors(@constructor id, string name, @type declaring_type_id, @constructor unbound_id): The key set {id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 3: +Tuple 1 in row 14: (897,"Nested",830,332) +Tuple 2 in row 15: (897,"Nested",830,1143) + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 830: @"(827).Nested;type". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.Nested;type" + Relevant element: Full ID for 332: @"(297)((296) p1);constructor". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.Nested;type"}({@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 830: @"(827).Nested;type". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.Nested;type" + Relevant element: Full ID for 1143: @"(297)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" +[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {name, parent_id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 34: (1005,"p1",1083,0,0,828,1138) +Tuple 2 in row 35: (1005,"p1",1083,0,0,828,1348) + Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1138: @"(1135)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1348: @"(813)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" +[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {name, parent_id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 42: (1031,"p1",1083,0,0,897,335) +Tuple 2 in row 43: (1031,"p1",1083,0,0,897,1146) + Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 335: @"(332)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 1146: @"(1143)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" +[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {name, parent_id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 36: (1006,"p2",1083,1,0,828,1140) +Tuple 2 in row 37: (1006,"p2",1083,1,0,828,1350) + Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1140: @"(1135)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1350: @"(813)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" +[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {index, parent_id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 34: (1005,"p1",1083,0,0,828,1138) +Tuple 2 in row 35: (1005,"p1",1083,0,0,828,1348) + Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1138: @"(1135)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1348: @"(813)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" +[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {index, parent_id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 42: (1031,"p1",1083,0,0,897,335) +Tuple 2 in row 43: (1031,"p1",1083,0,0,897,1146) + Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 335: @"(332)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 1146: @"(1143)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" +[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {index, parent_id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 36: (1006,"p2",1083,1,0,828,1140) +Tuple 2 in row 37: (1006,"p2",1083,1,0,828,1350) + Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1140: @"(1135)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1350: @"(813)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" +[INVALID_KEY] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 34: (1005,"p1",1083,0,0,828,1138) +Tuple 2 in row 35: (1005,"p1",1083,0,0,828,1348) + Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1138: @"(1135)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1348: @"(813)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" +[INVALID_KEY] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 36: (1006,"p2",1083,1,0,828,1140) +Tuple 2 in row 37: (1006,"p2",1083,1,0,828,1350) + Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1140: @"(1135)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" + Relevant element: Full ID for 1350: @"(813)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" +[INVALID_KEY] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {id} does not functionally determine all fields. +Here is a pair of tuples that agree on the key set but differ at index 6: +Tuple 1 in row 42: (1031,"p1",1083,0,0,897,335) +Tuple 2 in row 43: (1031,"p1",1083,0,0,897,1146) + Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 335: @"(332)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" + Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" + Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" + Relevant element: Full ID for 1146: @"(1143)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" diff --git a/csharp/ql/test/library-tests/methods/ExtensionMethods.expected b/csharp/ql/test/library-tests/methods/ExtensionMethods.expected index d7593f8f223..795014ea078 100644 --- a/csharp/ql/test/library-tests/methods/ExtensionMethods.expected +++ b/csharp/ql/test/library-tests/methods/ExtensionMethods.expected @@ -1,12 +1,12 @@ -| methods.cs:118:44:118:55 | call to method ToInt32 | 0 | methods.cs:118:52:118:54 | "0" | -| methods.cs:127:34:127:52 | call to method Slice | 0 | methods.cs:127:34:127:40 | access to local variable strings | -| methods.cs:127:34:127:52 | call to method Slice | 1 | methods.cs:127:48:127:48 | 1 | -| methods.cs:127:34:127:52 | call to method Slice | 2 | methods.cs:127:51:127:51 | 2 | -| methods.cs:129:42:129:52 | call to method ToInt32 | 0 | methods.cs:129:42:129:42 | access to local variable s | -| methods.cs:132:13:132:34 | call to method ToInt32 | 0 | methods.cs:132:32:132:33 | "" | -| methods.cs:132:13:132:34 | call to method ToInt32 | -1 | methods.cs:132:13:132:22 | access to type Extensions | -| methods.cs:134:13:134:49 | call to method ToBool | 0 | methods.cs:134:31:134:36 | "true" | -| methods.cs:134:13:134:49 | call to method ToBool | 1 | methods.cs:134:39:134:48 | delegate creation of type Func | -| methods.cs:134:13:134:49 | call to method ToBool | -1 | methods.cs:134:13:134:22 | access to type Extensions | -| methods.cs:180:20:180:39 | call to method SkipTwo | 0 | methods.cs:180:20:180:23 | access to parameter list | -| methods.cs:180:20:180:39 | call to method SkipTwo | 1 | methods.cs:180:38:180:38 | access to parameter i | +| methods.cs:119:44:119:55 | call to method ToInt32 | 0 | methods.cs:119:52:119:54 | "0" | +| methods.cs:128:34:128:52 | call to method Slice | 0 | methods.cs:128:34:128:40 | access to local variable strings | +| methods.cs:128:34:128:52 | call to method Slice | 1 | methods.cs:128:48:128:48 | 1 | +| methods.cs:128:34:128:52 | call to method Slice | 2 | methods.cs:128:51:128:51 | 2 | +| methods.cs:130:42:130:52 | call to method ToInt32 | 0 | methods.cs:130:42:130:42 | access to local variable s | +| methods.cs:133:13:133:34 | call to method ToInt32 | 0 | methods.cs:133:32:133:33 | "" | +| methods.cs:133:13:133:34 | call to method ToInt32 | -1 | methods.cs:133:13:133:22 | access to type Extensions | +| methods.cs:135:13:135:49 | call to method ToBool | 0 | methods.cs:135:31:135:36 | "true" | +| methods.cs:135:13:135:49 | call to method ToBool | 1 | methods.cs:135:39:135:48 | delegate creation of type Func | +| methods.cs:135:13:135:49 | call to method ToBool | -1 | methods.cs:135:13:135:22 | access to type Extensions | +| methods.cs:181:20:181:39 | call to method SkipTwo | 0 | methods.cs:181:20:181:23 | access to parameter list | +| methods.cs:181:20:181:39 | call to method SkipTwo | 1 | methods.cs:181:38:181:38 | access to parameter i | diff --git a/csharp/ql/test/library-tests/methods/Methods1.expected b/csharp/ql/test/library-tests/methods/Methods1.expected index be14a801185..054f358330f 100644 --- a/csharp/ql/test/library-tests/methods/Methods1.expected +++ b/csharp/ql/test/library-tests/methods/Methods1.expected @@ -1 +1 @@ -| methods.cs:9:21:9:24 | Swap | +| methods.cs:10:21:10:24 | Swap | diff --git a/csharp/ql/test/library-tests/methods/Methods2.expected b/csharp/ql/test/library-tests/methods/Methods2.expected index b9fad0aa394..d0dc1559fa6 100644 --- a/csharp/ql/test/library-tests/methods/Methods2.expected +++ b/csharp/ql/test/library-tests/methods/Methods2.expected @@ -1 +1 @@ -| methods.cs:28:28:28:33 | Divide | +| methods.cs:29:28:29:33 | Divide | diff --git a/csharp/ql/test/library-tests/methods/Methods3.expected b/csharp/ql/test/library-tests/methods/Methods3.expected index 8c726a4b6ff..1fb5f1dd0ba 100644 --- a/csharp/ql/test/library-tests/methods/Methods3.expected +++ b/csharp/ql/test/library-tests/methods/Methods3.expected @@ -1 +1 @@ -| methods.cs:49:11:49:25 | TestOverloading | +| methods.cs:50:11:50:25 | TestOverloading | diff --git a/csharp/ql/test/library-tests/methods/Methods4.expected b/csharp/ql/test/library-tests/methods/Methods4.expected index f709606a238..6eaa7230538 100644 --- a/csharp/ql/test/library-tests/methods/Methods4.expected +++ b/csharp/ql/test/library-tests/methods/Methods4.expected @@ -1 +1 @@ -| methods.cs:49:11:49:25 | TestOverloading | methods.cs:57:21:57:21 | F | Object | +| methods.cs:50:11:50:25 | TestOverloading | methods.cs:58:21:58:21 | F | Object | diff --git a/csharp/ql/test/library-tests/methods/Methods5.expected b/csharp/ql/test/library-tests/methods/Methods5.expected index 4f7e31d5bee..03638800b01 100644 --- a/csharp/ql/test/library-tests/methods/Methods5.expected +++ b/csharp/ql/test/library-tests/methods/Methods5.expected @@ -1,22 +1,30 @@ -| methods.cs:16:14:16:17 | Main | methods.cs:9:21:9:24 | Swap | methods.cs:6:18:6:24 | TestRef | -| methods.cs:16:14:16:17 | Main | methods.cs:46:28:46:36 | WriteLine | methods.cs:6:18:6:24 | TestRef | -| methods.cs:34:14:34:17 | Main | methods.cs:28:28:28:33 | Divide | methods.cs:25:18:25:24 | TestOut | -| methods.cs:34:14:34:17 | Main | methods.cs:46:28:46:36 | WriteLine | methods.cs:25:18:25:24 | TestOut | -| methods.cs:52:21:52:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:57:21:57:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:62:21:62:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:67:21:67:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:72:21:72:24 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:77:21:77:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:52:21:52:21 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:57:21:57:21 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:62:21:62:21 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:67:21:67:21 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:72:21:72:24 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:72:21:72:24 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:82:14:82:17 | Main | methods.cs:77:21:77:21 | F | methods.cs:49:11:49:25 | TestOverloading | -| methods.cs:118:27:118:37 | CallToInt32 | methods.cs:99:27:99:33 | ToInt32 | methods.cs:96:25:96:34 | Extensions | -| methods.cs:124:21:124:24 | Main | methods.cs:99:27:99:33 | ToInt32 | methods.cs:121:18:121:31 | TestExtensions | -| methods.cs:124:21:124:24 | Main | methods.cs:104:28:104:33 | ToBool | methods.cs:121:18:121:31 | TestExtensions | -| methods.cs:124:21:124:24 | Main | methods.cs:109:27:109:34 | Slice | methods.cs:121:18:121:31 | TestExtensions | -| methods.cs:178:67:178:76 | SkipTwoInt | methods.cs:173:65:173:74 | SkipTwo | methods.cs:166:18:166:47 | TestDefaultExtensionParameters | +| methods.cs:17:14:17:17 | Main | methods.cs:10:21:10:24 | Swap | methods.cs:7:18:7:24 | TestRef | +| methods.cs:17:14:17:17 | Main | methods.cs:47:28:47:36 | WriteLine | methods.cs:7:18:7:24 | TestRef | +| methods.cs:35:14:35:17 | Main | methods.cs:29:28:29:33 | Divide | methods.cs:26:18:26:24 | TestOut | +| methods.cs:35:14:35:17 | Main | methods.cs:47:28:47:36 | WriteLine | methods.cs:26:18:26:24 | TestOut | +| methods.cs:53:21:53:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:58:21:58:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:63:21:63:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:68:21:68:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:73:21:73:24 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:78:21:78:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:53:21:53:21 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:58:21:58:21 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:63:21:63:21 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:68:21:68:21 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:73:21:73:24 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:73:21:73:24 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:83:14:83:17 | Main | methods.cs:78:21:78:21 | F | methods.cs:50:11:50:25 | TestOverloading | +| methods.cs:119:27:119:37 | CallToInt32 | methods.cs:100:27:100:33 | ToInt32 | methods.cs:97:25:97:34 | Extensions | +| methods.cs:125:21:125:24 | Main | methods.cs:100:27:100:33 | ToInt32 | methods.cs:122:18:122:31 | TestExtensions | +| methods.cs:125:21:125:24 | Main | methods.cs:105:28:105:33 | ToBool | methods.cs:122:18:122:31 | TestExtensions | +| methods.cs:125:21:125:24 | Main | methods.cs:110:27:110:34 | Slice | methods.cs:122:18:122:31 | TestExtensions | +| methods.cs:179:67:179:76 | SkipTwoInt | methods.cs:174:65:174:74 | SkipTwo | methods.cs:167:18:167:47 | TestDefaultExtensionParameters | +| methods.cs:190:21:190:25 | Calls | methods.cs:187:21:187:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | +| methods.cs:190:21:190:25 | Calls | methods.cs:187:21:187:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | +| methods.cs:190:21:190:25 | Calls | methods.cs:188:21:188:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | +| methods.cs:190:21:190:25 | Calls | methods.cs:188:21:188:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | +| methods.cs:203:20:203:25 | Nested | methods.cs:202:20:202:25 | Nested | methods.cs:200:22:200:27 | Nested | +| methods.cs:203:20:203:25 | Nested | methods.cs:202:20:202:25 | Nested | methods.cs:200:22:200:27 | Nested | +| methods.cs:203:20:203:25 | Nested | methods.cs:203:20:203:25 | Nested | methods.cs:200:22:200:27 | Nested | +| methods.cs:203:20:203:25 | Nested | methods.cs:203:20:203:25 | Nested | methods.cs:200:22:200:27 | Nested | diff --git a/csharp/ql/test/library-tests/methods/Parameters1.expected b/csharp/ql/test/library-tests/methods/Parameters1.expected index 9d9948f38dd..e4e643616f6 100644 --- a/csharp/ql/test/library-tests/methods/Parameters1.expected +++ b/csharp/ql/test/library-tests/methods/Parameters1.expected @@ -1,2 +1,2 @@ -| methods.cs:9:21:9:24 | Swap | methods.cs:9:34:9:34 | x | -| methods.cs:9:21:9:24 | Swap | methods.cs:9:45:9:45 | y | +| methods.cs:10:21:10:24 | Swap | methods.cs:10:34:10:34 | x | +| methods.cs:10:21:10:24 | Swap | methods.cs:10:45:10:45 | y | diff --git a/csharp/ql/test/library-tests/methods/Parameters2.expected b/csharp/ql/test/library-tests/methods/Parameters2.expected index 645af10244f..30a7ca05274 100644 --- a/csharp/ql/test/library-tests/methods/Parameters2.expected +++ b/csharp/ql/test/library-tests/methods/Parameters2.expected @@ -1,4 +1,4 @@ -| methods.cs:28:28:28:33 | Divide | methods.cs:28:39:28:39 | x | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:46:28:46 | y | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:57:28:62 | result | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:73:28:81 | remainder | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:39:29:39 | x | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:46:29:46 | y | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:57:29:62 | result | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:73:29:81 | remainder | diff --git a/csharp/ql/test/library-tests/methods/Parameters3.expected b/csharp/ql/test/library-tests/methods/Parameters3.expected index 68936353065..ae1c5c02e80 100644 --- a/csharp/ql/test/library-tests/methods/Parameters3.expected +++ b/csharp/ql/test/library-tests/methods/Parameters3.expected @@ -1,2 +1,2 @@ -| methods.cs:45:28:45:32 | Write | Object[] | -| methods.cs:45:28:45:32 | Write | String | +| methods.cs:46:28:46:32 | Write | Object[] | +| methods.cs:46:28:46:32 | Write | String | diff --git a/csharp/ql/test/library-tests/methods/Parameters5.expected b/csharp/ql/test/library-tests/methods/Parameters5.expected index 823329fe908..1fd039430b1 100644 --- a/csharp/ql/test/library-tests/methods/Parameters5.expected +++ b/csharp/ql/test/library-tests/methods/Parameters5.expected @@ -1,7 +1,7 @@ -| methods.cs:145:40:145:40 | c | methods.cs:145:44:145:44 | 1 | 1 | -| methods.cs:145:51:145:51 | d | methods.cs:145:55:145:55 | 2 | 2 | -| methods.cs:145:65:145:65 | e | methods.cs:145:69:145:77 | ... + ... | ab | -| methods.cs:153:45:153:45 | x | methods.cs:153:49:153:53 | "abc" | abc | -| methods.cs:153:63:153:63 | y | methods.cs:153:67:153:78 | object creation of type Double | 0 | -| methods.cs:159:36:159:36 | y | methods.cs:159:40:159:40 | 0 | 0 | -| methods.cs:159:36:159:36 | y | methods.cs:159:40:159:40 | 0 | 0 | +| methods.cs:146:40:146:40 | c | methods.cs:146:44:146:44 | 1 | 1 | +| methods.cs:146:51:146:51 | d | methods.cs:146:55:146:55 | 2 | 2 | +| methods.cs:146:65:146:65 | e | methods.cs:146:69:146:77 | ... + ... | ab | +| methods.cs:154:45:154:45 | x | methods.cs:154:49:154:53 | "abc" | abc | +| methods.cs:154:63:154:63 | y | methods.cs:154:67:154:78 | object creation of type Double | 0 | +| methods.cs:160:36:160:36 | y | methods.cs:160:40:160:40 | 0 | 0 | +| methods.cs:160:36:160:36 | y | methods.cs:160:40:160:40 | 0 | 0 | diff --git a/csharp/ql/test/library-tests/methods/Parameters6.expected b/csharp/ql/test/library-tests/methods/Parameters6.expected index 25c2a9e1e9f..c431492acd1 100644 --- a/csharp/ql/test/library-tests/methods/Parameters6.expected +++ b/csharp/ql/test/library-tests/methods/Parameters6.expected @@ -1,2 +1,2 @@ -| methods.cs:157:40:157:40 | b | methods.cs:157:44:157:45 | 12 | 12 | -| methods.cs:157:55:157:55 | c | methods.cs:157:59:157:70 | object creation of type Double | 0 | +| methods.cs:158:40:158:40 | b | methods.cs:158:44:158:45 | 12 | 12 | +| methods.cs:158:55:158:55 | c | methods.cs:158:59:158:70 | object creation of type Double | 0 | diff --git a/csharp/ql/test/library-tests/methods/Parameters7.expected b/csharp/ql/test/library-tests/methods/Parameters7.expected index 372d22c8dfd..bbc0f36bae0 100644 --- a/csharp/ql/test/library-tests/methods/Parameters7.expected +++ b/csharp/ql/test/library-tests/methods/Parameters7.expected @@ -1 +1 @@ -| methods.cs:162:13:162:15 | value | +| methods.cs:163:13:163:15 | value | diff --git a/csharp/ql/test/library-tests/methods/Parameters8.expected b/csharp/ql/test/library-tests/methods/Parameters8.expected index d6bebaf61cc..6efd343a538 100644 --- a/csharp/ql/test/library-tests/methods/Parameters8.expected +++ b/csharp/ql/test/library-tests/methods/Parameters8.expected @@ -1,43 +1,59 @@ -| methods.cs:9:21:9:24 | Swap | methods.cs:9:34:9:34 | x | -| methods.cs:9:21:9:24 | Swap | methods.cs:9:45:9:45 | y | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:39:28:39 | x | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:46:28:46 | y | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:57:28:62 | result | -| methods.cs:28:28:28:33 | Divide | methods.cs:28:73:28:81 | remainder | -| methods.cs:45:28:45:32 | Write | methods.cs:45:41:45:43 | fmt | -| methods.cs:45:28:45:32 | Write | methods.cs:45:62:45:65 | args | -| methods.cs:46:28:46:36 | WriteLine | methods.cs:46:45:46:47 | fmt | -| methods.cs:46:28:46:36 | WriteLine | methods.cs:46:66:46:69 | args | -| methods.cs:57:21:57:21 | F | methods.cs:57:30:57:30 | x | -| methods.cs:62:21:62:21 | F | methods.cs:62:27:62:27 | x | -| methods.cs:67:21:67:21 | F | methods.cs:67:30:67:30 | x | -| methods.cs:72:21:72:24 | F | methods.cs:72:28:72:28 | x | -| methods.cs:72:21:72:24 | F | methods.cs:72:28:72:28 | x | -| methods.cs:72:21:72:24 | F | methods.cs:72:28:72:28 | x | -| methods.cs:77:21:77:21 | F | methods.cs:77:30:77:30 | x | -| methods.cs:77:21:77:21 | F | methods.cs:77:40:77:40 | y | -| methods.cs:99:27:99:33 | ToInt32 | methods.cs:99:35:99:47 | s | -| methods.cs:99:27:99:33 | ToInt32 | methods.cs:99:47:99:47 | s | -| methods.cs:104:28:104:33 | ToBool | methods.cs:104:47:104:47 | s | -| methods.cs:104:28:104:33 | ToBool | methods.cs:104:69:104:69 | f | -| methods.cs:109:27:109:34 | Slice | methods.cs:109:36:109:50 | source | -| methods.cs:109:27:109:34 | Slice | methods.cs:109:45:109:50 | source | -| methods.cs:109:27:109:34 | Slice | methods.cs:109:57:109:61 | index | -| methods.cs:109:27:109:34 | Slice | methods.cs:109:57:109:61 | index | -| methods.cs:109:27:109:34 | Slice | methods.cs:109:68:109:72 | count | -| methods.cs:109:27:109:34 | Slice | methods.cs:109:68:109:72 | count | -| methods.cs:141:14:141:20 | Method1 | methods.cs:141:26:141:26 | x | -| methods.cs:141:14:141:20 | Method1 | methods.cs:141:33:141:33 | y | -| methods.cs:145:14:145:20 | Method2 | methods.cs:145:26:145:26 | a | -| methods.cs:145:14:145:20 | Method2 | methods.cs:145:33:145:33 | b | -| methods.cs:145:14:145:20 | Method2 | methods.cs:145:40:145:40 | c | -| methods.cs:145:14:145:20 | Method2 | methods.cs:145:51:145:51 | d | -| methods.cs:145:14:145:20 | Method2 | methods.cs:145:65:145:65 | e | -| methods.cs:168:27:168:30 | Plus | methods.cs:168:41:168:44 | left | -| methods.cs:168:27:168:30 | Plus | methods.cs:168:51:168:55 | right | -| methods.cs:173:65:173:74 | SkipTwo | methods.cs:173:76:173:126 | list | -| methods.cs:173:65:173:74 | SkipTwo | methods.cs:173:123:173:126 | list | -| methods.cs:173:65:173:74 | SkipTwo | methods.cs:173:133:173:133 | i | -| methods.cs:173:65:173:74 | SkipTwo | methods.cs:173:133:173:133 | i | -| methods.cs:178:67:178:76 | SkipTwoInt | methods.cs:178:127:178:130 | list | -| methods.cs:178:67:178:76 | SkipTwoInt | methods.cs:178:137:178:137 | i | +| methods.cs:10:21:10:24 | Swap | methods.cs:10:34:10:34 | x | +| methods.cs:10:21:10:24 | Swap | methods.cs:10:45:10:45 | y | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:39:29:39 | x | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:46:29:46 | y | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:57:29:62 | result | +| methods.cs:29:28:29:33 | Divide | methods.cs:29:73:29:81 | remainder | +| methods.cs:46:28:46:32 | Write | methods.cs:46:41:46:43 | fmt | +| methods.cs:46:28:46:32 | Write | methods.cs:46:62:46:65 | args | +| methods.cs:47:28:47:36 | WriteLine | methods.cs:47:45:47:47 | fmt | +| methods.cs:47:28:47:36 | WriteLine | methods.cs:47:66:47:69 | args | +| methods.cs:58:21:58:21 | F | methods.cs:58:30:58:30 | x | +| methods.cs:63:21:63:21 | F | methods.cs:63:27:63:27 | x | +| methods.cs:68:21:68:21 | F | methods.cs:68:30:68:30 | x | +| methods.cs:73:21:73:24 | F | methods.cs:73:28:73:28 | x | +| methods.cs:73:21:73:24 | F | methods.cs:73:28:73:28 | x | +| methods.cs:73:21:73:24 | F | methods.cs:73:28:73:28 | x | +| methods.cs:78:21:78:21 | F | methods.cs:78:30:78:30 | x | +| methods.cs:78:21:78:21 | F | methods.cs:78:40:78:40 | y | +| methods.cs:100:27:100:33 | ToInt32 | methods.cs:100:35:100:47 | s | +| methods.cs:100:27:100:33 | ToInt32 | methods.cs:100:47:100:47 | s | +| methods.cs:105:28:105:33 | ToBool | methods.cs:105:47:105:47 | s | +| methods.cs:105:28:105:33 | ToBool | methods.cs:105:69:105:69 | f | +| methods.cs:110:27:110:34 | Slice | methods.cs:110:36:110:50 | source | +| methods.cs:110:27:110:34 | Slice | methods.cs:110:45:110:50 | source | +| methods.cs:110:27:110:34 | Slice | methods.cs:110:57:110:61 | index | +| methods.cs:110:27:110:34 | Slice | methods.cs:110:57:110:61 | index | +| methods.cs:110:27:110:34 | Slice | methods.cs:110:68:110:72 | count | +| methods.cs:110:27:110:34 | Slice | methods.cs:110:68:110:72 | count | +| methods.cs:142:14:142:20 | Method1 | methods.cs:142:26:142:26 | x | +| methods.cs:142:14:142:20 | Method1 | methods.cs:142:33:142:33 | y | +| methods.cs:146:14:146:20 | Method2 | methods.cs:146:26:146:26 | a | +| methods.cs:146:14:146:20 | Method2 | methods.cs:146:33:146:33 | b | +| methods.cs:146:14:146:20 | Method2 | methods.cs:146:40:146:40 | c | +| methods.cs:146:14:146:20 | Method2 | methods.cs:146:51:146:51 | d | +| methods.cs:146:14:146:20 | Method2 | methods.cs:146:65:146:65 | e | +| methods.cs:169:27:169:30 | Plus | methods.cs:169:41:169:44 | left | +| methods.cs:169:27:169:30 | Plus | methods.cs:169:51:169:55 | right | +| methods.cs:174:65:174:74 | SkipTwo | methods.cs:174:76:174:126 | list | +| methods.cs:174:65:174:74 | SkipTwo | methods.cs:174:123:174:126 | list | +| methods.cs:174:65:174:74 | SkipTwo | methods.cs:174:133:174:133 | i | +| methods.cs:174:65:174:74 | SkipTwo | methods.cs:174:133:174:133 | i | +| methods.cs:179:67:179:76 | SkipTwoInt | methods.cs:179:127:179:130 | list | +| methods.cs:179:67:179:76 | SkipTwoInt | methods.cs:179:137:179:137 | i | +| methods.cs:187:21:187:21 | M | methods.cs:187:25:187:26 | p1 | +| methods.cs:187:21:187:21 | M | methods.cs:187:25:187:26 | p1 | +| methods.cs:187:21:187:21 | M | methods.cs:187:25:187:26 | p1 | +| methods.cs:187:21:187:21 | M | methods.cs:187:33:187:34 | p2 | +| methods.cs:187:21:187:21 | M | methods.cs:187:33:187:34 | p2 | +| methods.cs:187:21:187:21 | M | methods.cs:187:33:187:34 | p2 | +| methods.cs:187:21:187:21 | M | methods.cs:188:27:188:28 | p1 | +| methods.cs:187:21:187:21 | M | methods.cs:188:35:188:36 | p2 | +| methods.cs:188:21:188:21 | M | methods.cs:187:25:187:26 | p1 | +| methods.cs:188:21:188:21 | M | methods.cs:187:33:187:34 | p2 | +| methods.cs:188:21:188:21 | M | methods.cs:188:27:188:28 | p1 | +| methods.cs:188:21:188:21 | M | methods.cs:188:27:188:28 | p1 | +| methods.cs:188:21:188:21 | M | methods.cs:188:27:188:28 | p1 | +| methods.cs:188:21:188:21 | M | methods.cs:188:35:188:36 | p2 | +| methods.cs:188:21:188:21 | M | methods.cs:188:35:188:36 | p2 | +| methods.cs:188:21:188:21 | M | methods.cs:188:35:188:36 | p2 | diff --git a/csharp/ql/test/library-tests/methods/Parameters9.expected b/csharp/ql/test/library-tests/methods/Parameters9.expected index 2af714b9abc..ee0a6ef0e53 100644 --- a/csharp/ql/test/library-tests/methods/Parameters9.expected +++ b/csharp/ql/test/library-tests/methods/Parameters9.expected @@ -1,7 +1,7 @@ -| methods.cs:145:40:145:40 | c | methods.cs:145:44:145:44 | 1 | Method2(int, int, int, int, string) | -| methods.cs:145:51:145:51 | d | methods.cs:145:55:145:55 | 2 | Method2(int, int, int, int, string) | -| methods.cs:145:65:145:65 | e | methods.cs:145:69:145:77 | ... + ... | Method2(int, int, int, int, string) | -| methods.cs:168:51:168:55 | right | methods.cs:168:59:168:59 | 0 | Plus(int, int) | -| methods.cs:173:133:173:133 | i | methods.cs:173:137:173:137 | 1 | SkipTwo(IEnumerable, int) | -| methods.cs:173:133:173:133 | i | methods.cs:173:137:173:137 | 1 | SkipTwo(IEnumerable, int) | -| methods.cs:178:137:178:137 | i | methods.cs:178:141:178:141 | 1 | SkipTwoInt(IEnumerable, int) | +| methods.cs:146:40:146:40 | c | methods.cs:146:44:146:44 | 1 | Method2(int, int, int, int, string) | +| methods.cs:146:51:146:51 | d | methods.cs:146:55:146:55 | 2 | Method2(int, int, int, int, string) | +| methods.cs:146:65:146:65 | e | methods.cs:146:69:146:77 | ... + ... | Method2(int, int, int, int, string) | +| methods.cs:169:51:169:55 | right | methods.cs:169:59:169:59 | 0 | Plus(int, int) | +| methods.cs:174:133:174:133 | i | methods.cs:174:137:174:137 | 1 | SkipTwo(IEnumerable, int) | +| methods.cs:174:133:174:133 | i | methods.cs:174:137:174:137 | 1 | SkipTwo(IEnumerable, int) | +| methods.cs:179:137:179:137 | i | methods.cs:179:141:179:141 | 1 | SkipTwoInt(IEnumerable, int) | diff --git a/csharp/ql/test/library-tests/methods/PrintAst.expected b/csharp/ql/test/library-tests/methods/PrintAst.expected index a41e0362094..a2220c63ea0 100644 --- a/csharp/ql/test/library-tests/methods/PrintAst.expected +++ b/csharp/ql/test/library-tests/methods/PrintAst.expected @@ -1,53 +1,44 @@ methods.cs: -# 3| [NamespaceDeclaration] namespace ... { ... } -# 6| 1: [Class] TestRef -# 9| 5: [Method] Swap -# 9| -1: [TypeMention] Void +# 4| [NamespaceDeclaration] namespace ... { ... } +# 7| 1: [Class] TestRef +# 10| 5: [Method] Swap +# 10| -1: [TypeMention] Void #-----| 2: (Parameters) -# 9| 0: [Parameter] x -# 9| -1: [TypeMention] int -# 9| 1: [Parameter] y -# 9| -1: [TypeMention] int -# 10| 4: [BlockStmt] {...} -# 11| 0: [LocalVariableDeclStmt] ... ...; -# 11| 0: [LocalVariableDeclAndInitExpr] Int32 temp = ... -# 11| -1: [TypeMention] int -# 11| 0: [LocalVariableAccess] access to local variable temp -# 11| 1: [ParameterAccess] access to parameter x -# 12| 1: [ExprStmt] ...; -# 12| 0: [AssignExpr] ... = ... -# 12| 0: [ParameterAccess] access to parameter x -# 12| 1: [ParameterAccess] access to parameter y -# 13| 2: [ExprStmt] ...; +# 10| 0: [Parameter] x +# 10| -1: [TypeMention] int +# 10| 1: [Parameter] y +# 10| -1: [TypeMention] int +# 11| 4: [BlockStmt] {...} +# 12| 0: [LocalVariableDeclStmt] ... ...; +# 12| 0: [LocalVariableDeclAndInitExpr] Int32 temp = ... +# 12| -1: [TypeMention] int +# 12| 0: [LocalVariableAccess] access to local variable temp +# 12| 1: [ParameterAccess] access to parameter x +# 13| 1: [ExprStmt] ...; # 13| 0: [AssignExpr] ... = ... -# 13| 0: [ParameterAccess] access to parameter y -# 13| 1: [LocalVariableAccess] access to local variable temp -# 16| 6: [Method] Main -# 16| -1: [TypeMention] Void -# 17| 4: [BlockStmt] {...} -# 18| 0: [LocalVariableDeclStmt] ... ...; -# 18| 0: [LocalVariableDeclAndInitExpr] Int32 i = ... -# 18| -1: [TypeMention] int -# 18| 0: [LocalVariableAccess] access to local variable i -# 18| 1: [IntLiteral] 1 -# 18| 1: [LocalVariableDeclAndInitExpr] Int32 j = ... -# 18| -1: [TypeMention] int -# 18| 0: [LocalVariableAccess] access to local variable j -# 18| 1: [IntLiteral] 2 -# 19| 1: [ExprStmt] ...; -# 19| 0: [MethodCall] call to method Swap +# 13| 0: [ParameterAccess] access to parameter x +# 13| 1: [ParameterAccess] access to parameter y +# 14| 2: [ExprStmt] ...; +# 14| 0: [AssignExpr] ... = ... +# 14| 0: [ParameterAccess] access to parameter y +# 14| 1: [LocalVariableAccess] access to local variable temp +# 17| 6: [Method] Main +# 17| -1: [TypeMention] Void +# 18| 4: [BlockStmt] {...} +# 19| 0: [LocalVariableDeclStmt] ... ...; +# 19| 0: [LocalVariableDeclAndInitExpr] Int32 i = ... +# 19| -1: [TypeMention] int # 19| 0: [LocalVariableAccess] access to local variable i -# 19| 1: [LocalVariableAccess] access to local variable j -# 20| 2: [ExprStmt] ...; -# 20| 0: [MethodCall] call to method WriteLine -# 20| -1: [TypeAccess] access to type Console -# 20| 0: [TypeMention] Console -# 20| 0: [StringLiteral] "{0} {1}" -# 20| 1: [CastExpr] (...) ... -# 20| 1: [LocalVariableAccess] access to local variable i -# 20| 2: [CastExpr] (...) ... -# 20| 1: [LocalVariableAccess] access to local variable j -# 21| 3: [ExprStmt] ...; +# 19| 1: [IntLiteral] 1 +# 19| 1: [LocalVariableDeclAndInitExpr] Int32 j = ... +# 19| -1: [TypeMention] int +# 19| 0: [LocalVariableAccess] access to local variable j +# 19| 1: [IntLiteral] 2 +# 20| 1: [ExprStmt] ...; +# 20| 0: [MethodCall] call to method Swap +# 20| 0: [LocalVariableAccess] access to local variable i +# 20| 1: [LocalVariableAccess] access to local variable j +# 21| 2: [ExprStmt] ...; # 21| 0: [MethodCall] call to method WriteLine # 21| -1: [TypeAccess] access to type Console # 21| 0: [TypeMention] Console @@ -56,65 +47,65 @@ methods.cs: # 21| 1: [LocalVariableAccess] access to local variable i # 21| 2: [CastExpr] (...) ... # 21| 1: [LocalVariableAccess] access to local variable j -# 25| 2: [Class] TestOut -# 28| 5: [Method] Divide -# 28| -1: [TypeMention] Void +# 22| 3: [ExprStmt] ...; +# 22| 0: [MethodCall] call to method WriteLine +# 22| -1: [TypeAccess] access to type Console +# 22| 0: [TypeMention] Console +# 22| 0: [StringLiteral] "{0} {1}" +# 22| 1: [CastExpr] (...) ... +# 22| 1: [LocalVariableAccess] access to local variable i +# 22| 2: [CastExpr] (...) ... +# 22| 1: [LocalVariableAccess] access to local variable j +# 26| 2: [Class] TestOut +# 29| 5: [Method] Divide +# 29| -1: [TypeMention] Void #-----| 2: (Parameters) -# 28| 0: [Parameter] x -# 28| -1: [TypeMention] int -# 28| 1: [Parameter] y -# 28| -1: [TypeMention] int -# 28| 2: [Parameter] result -# 28| -1: [TypeMention] int -# 28| 3: [Parameter] remainder -# 28| -1: [TypeMention] int -# 29| 4: [BlockStmt] {...} -# 30| 0: [ExprStmt] ...; -# 30| 0: [AssignExpr] ... = ... -# 30| 0: [ParameterAccess] access to parameter result -# 30| 1: [DivExpr] ... / ... -# 30| 0: [ParameterAccess] access to parameter x -# 30| 1: [ParameterAccess] access to parameter y -# 31| 1: [ExprStmt] ...; +# 29| 0: [Parameter] x +# 29| -1: [TypeMention] int +# 29| 1: [Parameter] y +# 29| -1: [TypeMention] int +# 29| 2: [Parameter] result +# 29| -1: [TypeMention] int +# 29| 3: [Parameter] remainder +# 29| -1: [TypeMention] int +# 30| 4: [BlockStmt] {...} +# 31| 0: [ExprStmt] ...; # 31| 0: [AssignExpr] ... = ... -# 31| 0: [ParameterAccess] access to parameter remainder -# 31| 1: [RemExpr] ... % ... +# 31| 0: [ParameterAccess] access to parameter result +# 31| 1: [DivExpr] ... / ... # 31| 0: [ParameterAccess] access to parameter x # 31| 1: [ParameterAccess] access to parameter y -# 34| 6: [Method] Main -# 34| -1: [TypeMention] Void -# 35| 4: [BlockStmt] {...} -# 36| 0: [LocalVariableDeclStmt] ... ...; -# 36| 0: [LocalVariableDeclExpr] Int32 res -# 36| 0: [TypeMention] int -# 36| 1: [LocalVariableDeclExpr] Int32 rem -# 36| 0: [TypeMention] int -# 37| 1: [ExprStmt] ...; -# 37| 0: [MethodCall] call to method Divide -# 37| 0: [IntLiteral] 10 -# 37| 1: [IntLiteral] 3 -# 37| 2: [LocalVariableAccess] access to local variable res -# 37| 3: [LocalVariableAccess] access to local variable rem -# 38| 2: [ExprStmt] ...; -# 38| 0: [MethodCall] call to method WriteLine -# 38| -1: [TypeAccess] access to type Console -# 38| 0: [TypeMention] Console -# 38| 0: [StringLiteral] "{0} {1}" -# 38| 1: [CastExpr] (...) ... -# 38| 1: [LocalVariableAccess] access to local variable res -# 38| 2: [CastExpr] (...) ... -# 38| 1: [LocalVariableAccess] access to local variable rem -# 42| 3: [Class] Console -# 45| 5: [Method] Write -# 45| -1: [TypeMention] Void -#-----| 2: (Parameters) -# 45| 0: [Parameter] fmt -# 45| -1: [TypeMention] string -# 45| 1: [Parameter] args -# 45| -1: [TypeMention] Object[] -# 45| 1: [TypeMention] object -# 45| 4: [BlockStmt] {...} -# 46| 6: [Method] WriteLine +# 32| 1: [ExprStmt] ...; +# 32| 0: [AssignExpr] ... = ... +# 32| 0: [ParameterAccess] access to parameter remainder +# 32| 1: [RemExpr] ... % ... +# 32| 0: [ParameterAccess] access to parameter x +# 32| 1: [ParameterAccess] access to parameter y +# 35| 6: [Method] Main +# 35| -1: [TypeMention] Void +# 36| 4: [BlockStmt] {...} +# 37| 0: [LocalVariableDeclStmt] ... ...; +# 37| 0: [LocalVariableDeclExpr] Int32 res +# 37| 0: [TypeMention] int +# 37| 1: [LocalVariableDeclExpr] Int32 rem +# 37| 0: [TypeMention] int +# 38| 1: [ExprStmt] ...; +# 38| 0: [MethodCall] call to method Divide +# 38| 0: [IntLiteral] 10 +# 38| 1: [IntLiteral] 3 +# 38| 2: [LocalVariableAccess] access to local variable res +# 38| 3: [LocalVariableAccess] access to local variable rem +# 39| 2: [ExprStmt] ...; +# 39| 0: [MethodCall] call to method WriteLine +# 39| -1: [TypeAccess] access to type Console +# 39| 0: [TypeMention] Console +# 39| 0: [StringLiteral] "{0} {1}" +# 39| 1: [CastExpr] (...) ... +# 39| 1: [LocalVariableAccess] access to local variable res +# 39| 2: [CastExpr] (...) ... +# 39| 1: [LocalVariableAccess] access to local variable rem +# 43| 3: [Class] Console +# 46| 5: [Method] Write # 46| -1: [TypeMention] Void #-----| 2: (Parameters) # 46| 0: [Parameter] fmt @@ -123,354 +114,452 @@ methods.cs: # 46| -1: [TypeMention] Object[] # 46| 1: [TypeMention] object # 46| 4: [BlockStmt] {...} -# 49| 4: [Class] TestOverloading -# 52| 5: [Method] F -# 52| -1: [TypeMention] Void -# 53| 4: [BlockStmt] {...} -# 54| 0: [ExprStmt] ...; -# 54| 0: [MethodCall] call to method WriteLine -# 54| -1: [TypeAccess] access to type Console -# 54| 0: [TypeMention] Console -# 54| 0: [StringLiteral] "F()" -# 57| 6: [Method] F -# 57| -1: [TypeMention] Void +# 47| 6: [Method] WriteLine +# 47| -1: [TypeMention] Void #-----| 2: (Parameters) -# 57| 0: [Parameter] x -# 57| -1: [TypeMention] object -# 58| 4: [BlockStmt] {...} -# 59| 0: [ExprStmt] ...; -# 59| 0: [MethodCall] call to method WriteLine -# 59| -1: [TypeAccess] access to type Console -# 59| 0: [TypeMention] Console -# 59| 0: [StringLiteral] "F(object)" -# 62| 7: [Method] F -# 62| -1: [TypeMention] Void +# 47| 0: [Parameter] fmt +# 47| -1: [TypeMention] string +# 47| 1: [Parameter] args +# 47| -1: [TypeMention] Object[] +# 47| 1: [TypeMention] object +# 47| 4: [BlockStmt] {...} +# 50| 4: [Class] TestOverloading +# 53| 5: [Method] F +# 53| -1: [TypeMention] Void +# 54| 4: [BlockStmt] {...} +# 55| 0: [ExprStmt] ...; +# 55| 0: [MethodCall] call to method WriteLine +# 55| -1: [TypeAccess] access to type Console +# 55| 0: [TypeMention] Console +# 55| 0: [StringLiteral] "F()" +# 58| 6: [Method] F +# 58| -1: [TypeMention] Void #-----| 2: (Parameters) -# 62| 0: [Parameter] x -# 62| -1: [TypeMention] int -# 63| 4: [BlockStmt] {...} -# 64| 0: [ExprStmt] ...; -# 64| 0: [MethodCall] call to method WriteLine -# 64| -1: [TypeAccess] access to type Console -# 64| 0: [TypeMention] Console -# 64| 0: [StringLiteral] "F(int)" -# 67| 8: [Method] F -# 67| -1: [TypeMention] Void +# 58| 0: [Parameter] x +# 58| -1: [TypeMention] object +# 59| 4: [BlockStmt] {...} +# 60| 0: [ExprStmt] ...; +# 60| 0: [MethodCall] call to method WriteLine +# 60| -1: [TypeAccess] access to type Console +# 60| 0: [TypeMention] Console +# 60| 0: [StringLiteral] "F(object)" +# 63| 7: [Method] F +# 63| -1: [TypeMention] Void #-----| 2: (Parameters) -# 67| 0: [Parameter] x -# 67| -1: [TypeMention] double -# 68| 4: [BlockStmt] {...} -# 69| 0: [ExprStmt] ...; -# 69| 0: [MethodCall] call to method WriteLine -# 69| -1: [TypeAccess] access to type Console -# 69| 0: [TypeMention] Console -# 69| 0: [StringLiteral] "F(double)" -# 72| 9: [Method] F -# 72| -1: [TypeMention] Void +# 63| 0: [Parameter] x +# 63| -1: [TypeMention] int +# 64| 4: [BlockStmt] {...} +# 65| 0: [ExprStmt] ...; +# 65| 0: [MethodCall] call to method WriteLine +# 65| -1: [TypeAccess] access to type Console +# 65| 0: [TypeMention] Console +# 65| 0: [StringLiteral] "F(int)" +# 68| 8: [Method] F +# 68| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 68| 0: [Parameter] x +# 68| -1: [TypeMention] double +# 69| 4: [BlockStmt] {...} +# 70| 0: [ExprStmt] ...; +# 70| 0: [MethodCall] call to method WriteLine +# 70| -1: [TypeAccess] access to type Console +# 70| 0: [TypeMention] Console +# 70| 0: [StringLiteral] "F(double)" +# 73| 9: [Method] F +# 73| -1: [TypeMention] Void #-----| 1: (Type parameters) -# 72| 0: [TypeParameter] T +# 73| 0: [TypeParameter] T #-----| 2: (Parameters) -# 72| 0: [Parameter] x -# 72| -1: [TypeMention] T -# 73| 4: [BlockStmt] {...} -# 74| 0: [ExprStmt] ...; -# 74| 0: [MethodCall] call to method WriteLine -# 74| -1: [TypeAccess] access to type Console -# 74| 0: [TypeMention] Console -# 74| 0: [StringLiteral] "F(T)" -# 77| 12: [Method] F -# 77| -1: [TypeMention] Void +# 73| 0: [Parameter] x +# 73| -1: [TypeMention] T +# 74| 4: [BlockStmt] {...} +# 75| 0: [ExprStmt] ...; +# 75| 0: [MethodCall] call to method WriteLine +# 75| -1: [TypeAccess] access to type Console +# 75| 0: [TypeMention] Console +# 75| 0: [StringLiteral] "F(T)" +# 78| 12: [Method] F +# 78| -1: [TypeMention] Void #-----| 2: (Parameters) -# 77| 0: [Parameter] x -# 77| -1: [TypeMention] double -# 77| 1: [Parameter] y -# 77| -1: [TypeMention] double -# 78| 4: [BlockStmt] {...} -# 79| 0: [ExprStmt] ...; -# 79| 0: [MethodCall] call to method WriteLine -# 79| -1: [TypeAccess] access to type Console -# 79| 0: [TypeMention] Console -# 79| 0: [StringLiteral] "F(double, double)" -# 82| 13: [Method] Main -# 82| -1: [TypeMention] Void -# 83| 4: [BlockStmt] {...} -# 84| 0: [ExprStmt] ...; -# 84| 0: [MethodCall] call to method F -# 85| 1: [ExprStmt] ...; +# 78| 0: [Parameter] x +# 78| -1: [TypeMention] double +# 78| 1: [Parameter] y +# 78| -1: [TypeMention] double +# 79| 4: [BlockStmt] {...} +# 80| 0: [ExprStmt] ...; +# 80| 0: [MethodCall] call to method WriteLine +# 80| -1: [TypeAccess] access to type Console +# 80| 0: [TypeMention] Console +# 80| 0: [StringLiteral] "F(double, double)" +# 83| 13: [Method] Main +# 83| -1: [TypeMention] Void +# 84| 4: [BlockStmt] {...} +# 85| 0: [ExprStmt] ...; # 85| 0: [MethodCall] call to method F -# 85| 0: [IntLiteral] 1 -# 86| 2: [ExprStmt] ...; +# 86| 1: [ExprStmt] ...; # 86| 0: [MethodCall] call to method F -# 86| 0: [DoubleLiteral] 1 -# 87| 3: [ExprStmt] ...; +# 86| 0: [IntLiteral] 1 +# 87| 2: [ExprStmt] ...; # 87| 0: [MethodCall] call to method F -# 87| 0: [StringLiteral] "abc" -# 88| 4: [ExprStmt] ...; +# 87| 0: [DoubleLiteral] 1 +# 88| 3: [ExprStmt] ...; # 88| 0: [MethodCall] call to method F -# 88| 0: [CastExpr] (...) ... -# 88| 0: [TypeAccess] access to type Double -# 88| 0: [TypeMention] double -# 88| 1: [IntLiteral] 1 -# 89| 5: [ExprStmt] ...; +# 88| 0: [StringLiteral] "abc" +# 89| 4: [ExprStmt] ...; # 89| 0: [MethodCall] call to method F # 89| 0: [CastExpr] (...) ... -# 89| 0: [TypeAccess] access to type Object -# 89| 0: [TypeMention] object +# 89| 0: [TypeAccess] access to type Double +# 89| 0: [TypeMention] double # 89| 1: [IntLiteral] 1 -# 90| 6: [ExprStmt] ...; +# 90| 5: [ExprStmt] ...; # 90| 0: [MethodCall] call to method F -# 90| 0: [IntLiteral] 1 -# 91| 7: [ExprStmt] ...; +# 90| 0: [CastExpr] (...) ... +# 90| 0: [TypeAccess] access to type Object +# 90| 0: [TypeMention] object +# 90| 1: [IntLiteral] 1 +# 91| 6: [ExprStmt] ...; # 91| 0: [MethodCall] call to method F -# 91| 0: [CastExpr] (...) ... -# 91| 1: [IntLiteral] 1 -# 91| 1: [CastExpr] (...) ... -# 91| 1: [IntLiteral] 1 -# 96| 5: [Class] Extensions -# 99| 4: [ExtensionMethod] ToInt32 -# 99| -1: [TypeMention] int +# 91| 0: [IntLiteral] 1 +# 92| 7: [ExprStmt] ...; +# 92| 0: [MethodCall] call to method F +# 92| 0: [CastExpr] (...) ... +# 92| 1: [IntLiteral] 1 +# 92| 1: [CastExpr] (...) ... +# 92| 1: [IntLiteral] 1 +# 97| 5: [Class] Extensions +# 100| 4: [ExtensionMethod] ToInt32 +# 100| -1: [TypeMention] int #-----| 2: (Parameters) -# 99| 0: [Parameter] s -# 99| -1: [TypeMention] string -# 100| 4: [BlockStmt] {...} -# 101| 0: [ReturnStmt] return ...; -# 101| 0: [MethodCall] call to method Parse -# 101| -1: [TypeAccess] access to type Int32 -# 101| 0: [TypeMention] int -# 101| 0: [ParameterAccess] access to parameter s -# 104| 5: [ExtensionMethod] ToBool -# 104| -1: [TypeMention] bool +# 100| 0: [Parameter] s +# 100| -1: [TypeMention] string +# 101| 4: [BlockStmt] {...} +# 102| 0: [ReturnStmt] return ...; +# 102| 0: [MethodCall] call to method Parse +# 102| -1: [TypeAccess] access to type Int32 +# 102| 0: [TypeMention] int +# 102| 0: [ParameterAccess] access to parameter s +# 105| 5: [ExtensionMethod] ToBool +# 105| -1: [TypeMention] bool #-----| 2: (Parameters) -# 104| 0: [Parameter] s -# 104| -1: [TypeMention] string -# 104| 1: [Parameter] f -# 104| -1: [TypeMention] Func -# 104| 1: [TypeMention] string -# 104| 2: [TypeMention] bool -# 105| 4: [BlockStmt] {...} -# 106| 0: [ReturnStmt] return ...; -# 106| 0: [DelegateCall] delegate call -# 106| -1: [ParameterAccess] access to parameter f -# 106| 0: [ParameterAccess] access to parameter s -# 109| 6: [ExtensionMethod] Slice -# 109| -1: [TypeMention] T[] -# 109| 1: [TypeMention] T +# 105| 0: [Parameter] s +# 105| -1: [TypeMention] string +# 105| 1: [Parameter] f +# 105| -1: [TypeMention] Func +# 105| 1: [TypeMention] string +# 105| 2: [TypeMention] bool +# 106| 4: [BlockStmt] {...} +# 107| 0: [ReturnStmt] return ...; +# 107| 0: [DelegateCall] delegate call +# 107| -1: [ParameterAccess] access to parameter f +# 107| 0: [ParameterAccess] access to parameter s +# 110| 6: [ExtensionMethod] Slice +# 110| -1: [TypeMention] T[] +# 110| 1: [TypeMention] T #-----| 1: (Type parameters) -# 109| 0: [TypeParameter] T +# 110| 0: [TypeParameter] T #-----| 2: (Parameters) -# 109| 0: [Parameter] source -# 109| -1: [TypeMention] T[] -# 109| 1: [TypeMention] T -# 109| 1: [Parameter] index -# 109| -1: [TypeMention] int -# 109| 2: [Parameter] count -# 109| -1: [TypeMention] int -# 110| 4: [BlockStmt] {...} -# 111| 0: [IfStmt] if (...) ... -# 111| 0: [LogicalOrExpr] ... || ... -# 111| 0: [LogicalOrExpr] ... || ... -# 111| 0: [LTExpr] ... < ... -# 111| 0: [ParameterAccess] access to parameter index -# 111| 1: [IntLiteral] 0 -# 111| 1: [LTExpr] ... < ... -# 111| 0: [ParameterAccess] access to parameter count -# 111| 1: [IntLiteral] 0 -# 111| 1: [LTExpr] ... < ... -# 111| 0: [SubExpr] ... - ... -# 111| 0: [PropertyCall] access to property Length -# 111| -1: [ParameterAccess] access to parameter source -# 111| 1: [ParameterAccess] access to parameter index -# 111| 1: [ParameterAccess] access to parameter count -# 112| 1: [ThrowStmt] throw ...; -# 112| 0: [ObjectCreation] object creation of type ArgumentException -# 112| 0: [TypeMention] ArgumentException -# 113| 1: [LocalVariableDeclStmt] ... ...; -# 113| 0: [LocalVariableDeclAndInitExpr] T[] result = ... -# 113| -1: [TypeMention] T[] -# 113| 1: [TypeMention] T -# 113| 0: [LocalVariableAccess] access to local variable result -# 113| 1: [ArrayCreation] array creation of type T[] -# 113| -1: [TypeMention] T[] -# 113| 1: [TypeMention] T -# 113| 0: [ParameterAccess] access to parameter count -# 114| 2: [ExprStmt] ...; -# 114| 0: [MethodCall] call to method Copy -# 114| -1: [TypeAccess] access to type Array -# 114| 0: [TypeMention] Array -# 114| 0: [ParameterAccess] access to parameter source -# 114| 1: [ParameterAccess] access to parameter index -# 114| 2: [LocalVariableAccess] access to local variable result -# 114| 3: [IntLiteral] 0 -# 114| 4: [ParameterAccess] access to parameter count -# 115| 3: [ReturnStmt] return ...; -# 115| 0: [LocalVariableAccess] access to local variable result -# 118| 8: [Method] CallToInt32 -# 118| -1: [TypeMention] int -# 118| 4: [MethodCall] call to method ToInt32 -# 118| 0: [StringLiteral] "0" -# 121| 6: [Class] TestExtensions -# 124| 4: [Method] Main -# 124| -1: [TypeMention] Void -# 125| 4: [BlockStmt] {...} -# 126| 0: [LocalVariableDeclStmt] ... ...; -# 126| 0: [LocalVariableDeclAndInitExpr] String[] strings = ... -# 126| -1: [TypeMention] String[] -# 126| 1: [TypeMention] string -# 126| 0: [LocalVariableAccess] access to local variable strings -# 126| 1: [ArrayCreation] array creation of type String[] -# 126| -1: [ArrayInitializer] { ..., ... } -# 126| 0: [StringLiteral] "1" -# 126| 1: [StringLiteral] "22" -# 126| 2: [StringLiteral] "333" -# 126| 3: [StringLiteral] "4444" -# 127| 1: [ForeachStmt] foreach (... ... in ...) ... -# 127| 0: [LocalVariableDeclExpr] String s -# 127| 0: [TypeMention] string -# 127| 1: [MethodCall] call to method Slice -# 127| -1: [LocalVariableAccess] access to local variable strings -# 127| 0: [IntLiteral] 1 -# 127| 1: [IntLiteral] 2 -# 128| 2: [BlockStmt] {...} -# 129| 0: [ExprStmt] ...; -# 129| 0: [MethodCall] call to method WriteLine -# 129| -1: [TypeAccess] access to type Console -# 129| 0: [TypeMention] Console -# 129| 0: [MethodCall] call to method ToInt32 -# 129| -1: [LocalVariableAccess] access to local variable s -# 132| 2: [ExprStmt] ...; -# 132| 0: [MethodCall] call to method ToInt32 -# 132| -1: [TypeAccess] access to type Extensions -# 132| 0: [TypeMention] Extensions -# 132| 0: [StringLiteral] "" -# 134| 3: [ExprStmt] ...; -# 134| 0: [MethodCall] call to method ToBool -# 134| -1: [TypeAccess] access to type Extensions -# 134| 0: [TypeMention] Extensions -# 134| 0: [StringLiteral] "true" -# 134| 1: [ImplicitDelegateCreation] delegate creation of type Func -# 134| 0: [MethodAccess] access to method Parse -# 134| -1: [TypeAccess] access to type Boolean -# 134| 0: [TypeMention] bool -# 139| 7: [Class] TestDefaultParameters -# 141| 4: [Method] Method1 -# 141| -1: [TypeMention] Void +# 110| 0: [Parameter] source +# 110| -1: [TypeMention] T[] +# 110| 1: [TypeMention] T +# 110| 1: [Parameter] index +# 110| -1: [TypeMention] int +# 110| 2: [Parameter] count +# 110| -1: [TypeMention] int +# 111| 4: [BlockStmt] {...} +# 112| 0: [IfStmt] if (...) ... +# 112| 0: [LogicalOrExpr] ... || ... +# 112| 0: [LogicalOrExpr] ... || ... +# 112| 0: [LTExpr] ... < ... +# 112| 0: [ParameterAccess] access to parameter index +# 112| 1: [IntLiteral] 0 +# 112| 1: [LTExpr] ... < ... +# 112| 0: [ParameterAccess] access to parameter count +# 112| 1: [IntLiteral] 0 +# 112| 1: [LTExpr] ... < ... +# 112| 0: [SubExpr] ... - ... +# 112| 0: [PropertyCall] access to property Length +# 112| -1: [ParameterAccess] access to parameter source +# 112| 1: [ParameterAccess] access to parameter index +# 112| 1: [ParameterAccess] access to parameter count +# 113| 1: [ThrowStmt] throw ...; +# 113| 0: [ObjectCreation] object creation of type ArgumentException +# 113| 0: [TypeMention] ArgumentException +# 114| 1: [LocalVariableDeclStmt] ... ...; +# 114| 0: [LocalVariableDeclAndInitExpr] T[] result = ... +# 114| -1: [TypeMention] T[] +# 114| 1: [TypeMention] T +# 114| 0: [LocalVariableAccess] access to local variable result +# 114| 1: [ArrayCreation] array creation of type T[] +# 114| -1: [TypeMention] T[] +# 114| 1: [TypeMention] T +# 114| 0: [ParameterAccess] access to parameter count +# 115| 2: [ExprStmt] ...; +# 115| 0: [MethodCall] call to method Copy +# 115| -1: [TypeAccess] access to type Array +# 115| 0: [TypeMention] Array +# 115| 0: [ParameterAccess] access to parameter source +# 115| 1: [ParameterAccess] access to parameter index +# 115| 2: [LocalVariableAccess] access to local variable result +# 115| 3: [IntLiteral] 0 +# 115| 4: [ParameterAccess] access to parameter count +# 116| 3: [ReturnStmt] return ...; +# 116| 0: [LocalVariableAccess] access to local variable result +# 119| 8: [Method] CallToInt32 +# 119| -1: [TypeMention] int +# 119| 4: [MethodCall] call to method ToInt32 +# 119| 0: [StringLiteral] "0" +# 122| 6: [Class] TestExtensions +# 125| 4: [Method] Main +# 125| -1: [TypeMention] Void +# 126| 4: [BlockStmt] {...} +# 127| 0: [LocalVariableDeclStmt] ... ...; +# 127| 0: [LocalVariableDeclAndInitExpr] String[] strings = ... +# 127| -1: [TypeMention] String[] +# 127| 1: [TypeMention] string +# 127| 0: [LocalVariableAccess] access to local variable strings +# 127| 1: [ArrayCreation] array creation of type String[] +# 127| -1: [ArrayInitializer] { ..., ... } +# 127| 0: [StringLiteral] "1" +# 127| 1: [StringLiteral] "22" +# 127| 2: [StringLiteral] "333" +# 127| 3: [StringLiteral] "4444" +# 128| 1: [ForeachStmt] foreach (... ... in ...) ... +# 128| 0: [LocalVariableDeclExpr] String s +# 128| 0: [TypeMention] string +# 128| 1: [MethodCall] call to method Slice +# 128| -1: [LocalVariableAccess] access to local variable strings +# 128| 0: [IntLiteral] 1 +# 128| 1: [IntLiteral] 2 +# 129| 2: [BlockStmt] {...} +# 130| 0: [ExprStmt] ...; +# 130| 0: [MethodCall] call to method WriteLine +# 130| -1: [TypeAccess] access to type Console +# 130| 0: [TypeMention] Console +# 130| 0: [MethodCall] call to method ToInt32 +# 130| -1: [LocalVariableAccess] access to local variable s +# 133| 2: [ExprStmt] ...; +# 133| 0: [MethodCall] call to method ToInt32 +# 133| -1: [TypeAccess] access to type Extensions +# 133| 0: [TypeMention] Extensions +# 133| 0: [StringLiteral] "" +# 135| 3: [ExprStmt] ...; +# 135| 0: [MethodCall] call to method ToBool +# 135| -1: [TypeAccess] access to type Extensions +# 135| 0: [TypeMention] Extensions +# 135| 0: [StringLiteral] "true" +# 135| 1: [ImplicitDelegateCreation] delegate creation of type Func +# 135| 0: [MethodAccess] access to method Parse +# 135| -1: [TypeAccess] access to type Boolean +# 135| 0: [TypeMention] bool +# 140| 7: [Class] TestDefaultParameters +# 142| 4: [Method] Method1 +# 142| -1: [TypeMention] Void #-----| 2: (Parameters) -# 141| 0: [Parameter] x -# 141| -1: [TypeMention] int -# 141| 1: [Parameter] y -# 141| -1: [TypeMention] int -# 142| 4: [BlockStmt] {...} -# 145| 5: [Method] Method2 -# 145| -1: [TypeMention] Void +# 142| 0: [Parameter] x +# 142| -1: [TypeMention] int +# 142| 1: [Parameter] y +# 142| -1: [TypeMention] int +# 143| 4: [BlockStmt] {...} +# 146| 5: [Method] Method2 +# 146| -1: [TypeMention] Void #-----| 2: (Parameters) -# 145| 0: [Parameter] a -# 145| -1: [TypeMention] int -# 145| 1: [Parameter] b -# 145| -1: [TypeMention] int -# 145| 2: [Parameter] c -# 145| -1: [TypeMention] int -# 145| 1: [IntLiteral] 1 -# 145| 3: [Parameter] d -# 145| -1: [TypeMention] int -# 145| 1: [IntLiteral] 2 -# 145| 4: [Parameter] e -# 145| -1: [TypeMention] string -# 145| 1: [AddExpr] ... + ... -# 145| 0: [StringLiteral] "a" -# 145| 1: [StringLiteral] "b" -# 146| 4: [BlockStmt] {...} -# 149| 6: [InstanceConstructor] TestDefaultParameters +# 146| 0: [Parameter] a +# 146| -1: [TypeMention] int +# 146| 1: [Parameter] b +# 146| -1: [TypeMention] int +# 146| 2: [Parameter] c +# 146| -1: [TypeMention] int +# 146| 1: [IntLiteral] 1 +# 146| 3: [Parameter] d +# 146| -1: [TypeMention] int +# 146| 1: [IntLiteral] 2 +# 146| 4: [Parameter] e +# 146| -1: [TypeMention] string +# 146| 1: [AddExpr] ... + ... +# 146| 0: [StringLiteral] "a" +# 146| 1: [StringLiteral] "b" +# 147| 4: [BlockStmt] {...} +# 150| 6: [InstanceConstructor] TestDefaultParameters #-----| 2: (Parameters) -# 149| 0: [Parameter] x -# 149| -1: [TypeMention] int -# 150| 4: [BlockStmt] {...} -# 153| 7: [InstanceConstructor] TestDefaultParameters +# 150| 0: [Parameter] x +# 150| -1: [TypeMention] int +# 151| 4: [BlockStmt] {...} +# 154| 7: [InstanceConstructor] TestDefaultParameters #-----| 2: (Parameters) -# 153| 0: [Parameter] x -# 153| -1: [TypeMention] string -# 153| 1: [StringLiteral] "abc" -# 153| 1: [Parameter] y -# 153| -1: [TypeMention] double -# 153| 1: [ObjectCreation] object creation of type Double -# 153| 0: [TypeMention] double -# 154| 4: [BlockStmt] {...} -# 157| 8: [DelegateType] Del +# 154| 0: [Parameter] x +# 154| -1: [TypeMention] string +# 154| 1: [StringLiteral] "abc" +# 154| 1: [Parameter] y +# 154| -1: [TypeMention] double +# 154| 1: [ObjectCreation] object creation of type Double +# 154| 0: [TypeMention] double +# 155| 4: [BlockStmt] {...} +# 158| 8: [DelegateType] Del #-----| 2: (Parameters) -# 157| 0: [Parameter] a -# 157| -1: [TypeMention] string -# 157| 1: [Parameter] b -# 157| -1: [TypeMention] int -# 157| 1: [IntLiteral] 12 -# 157| 2: [Parameter] c -# 157| -1: [TypeMention] double -# 157| 1: [ObjectCreation] object creation of type Double -# 157| 0: [TypeMention] double -# 159| 9: [Indexer] Item -# 159| -1: [TypeMention] int +# 158| 0: [Parameter] a +# 158| -1: [TypeMention] string +# 158| 1: [Parameter] b +# 158| -1: [TypeMention] int +# 158| 1: [IntLiteral] 12 +# 158| 2: [Parameter] c +# 158| -1: [TypeMention] double +# 158| 1: [ObjectCreation] object creation of type Double +# 158| 0: [TypeMention] double +# 160| 9: [Indexer] Item +# 160| -1: [TypeMention] int #-----| 1: (Parameters) -# 159| 0: [Parameter] x -# 159| -1: [TypeMention] int -# 159| 1: [Parameter] y -# 159| -1: [TypeMention] int -# 159| 1: [IntLiteral] 0 -# 161| 3: [Getter] get_Item +# 160| 0: [Parameter] x +# 160| -1: [TypeMention] int +# 160| 1: [Parameter] y +# 160| -1: [TypeMention] int +# 160| 1: [IntLiteral] 0 +# 162| 3: [Getter] get_Item #-----| 2: (Parameters) -# 159| 0: [Parameter] x -# 159| 1: [Parameter] y -# 159| 1: [IntLiteral] 0 -# 161| 4: [BlockStmt] {...} -# 161| 0: [ReturnStmt] return ...; -# 161| 0: [AddExpr] ... + ... -# 161| 0: [ParameterAccess] access to parameter x -# 161| 1: [ParameterAccess] access to parameter y -# 162| 4: [Setter] set_Item -#-----| 2: (Parameters) -# 159| 0: [Parameter] x -# 159| 1: [Parameter] y -# 159| 1: [IntLiteral] 0 -# 162| 2: [Parameter] value +# 160| 0: [Parameter] x +# 160| 1: [Parameter] y +# 160| 1: [IntLiteral] 0 # 162| 4: [BlockStmt] {...} -# 166| 8: [Class] TestDefaultExtensionParameters -# 168| 4: [ExtensionMethod] Plus -# 168| -1: [TypeMention] int +# 162| 0: [ReturnStmt] return ...; +# 162| 0: [AddExpr] ... + ... +# 162| 0: [ParameterAccess] access to parameter x +# 162| 1: [ParameterAccess] access to parameter y +# 163| 4: [Setter] set_Item +#-----| 2: (Parameters) +# 160| 0: [Parameter] x +# 160| 1: [Parameter] y +# 160| 1: [IntLiteral] 0 +# 163| 2: [Parameter] value +# 163| 4: [BlockStmt] {...} +# 167| 8: [Class] TestDefaultExtensionParameters +# 169| 4: [ExtensionMethod] Plus +# 169| -1: [TypeMention] int #-----| 2: (Parameters) -# 168| 0: [Parameter] left -# 168| -1: [TypeMention] int -# 168| 1: [Parameter] right -# 168| -1: [TypeMention] int -# 168| 1: [IntLiteral] 0 -# 169| 4: [BlockStmt] {...} -# 170| 0: [ReturnStmt] return ...; -# 170| 0: [AddExpr] ... + ... -# 170| 0: [ParameterAccess] access to parameter left -# 170| 1: [ParameterAccess] access to parameter right -# 173| 5: [ExtensionMethod] SkipTwo -# 173| -1: [TypeMention] IEnumerable -# 173| 1: [TypeMention] T +# 169| 0: [Parameter] left +# 169| -1: [TypeMention] int +# 169| 1: [Parameter] right +# 169| -1: [TypeMention] int +# 169| 1: [IntLiteral] 0 +# 170| 4: [BlockStmt] {...} +# 171| 0: [ReturnStmt] return ...; +# 171| 0: [AddExpr] ... + ... +# 171| 0: [ParameterAccess] access to parameter left +# 171| 1: [ParameterAccess] access to parameter right +# 174| 5: [ExtensionMethod] SkipTwo +# 174| -1: [TypeMention] IEnumerable +# 174| 1: [TypeMention] T #-----| 1: (Type parameters) -# 173| 0: [TypeParameter] T +# 174| 0: [TypeParameter] T #-----| 2: (Parameters) -# 173| 0: [Parameter] list -# 173| -1: [TypeMention] IEnumerable -# 173| 1: [TypeMention] T -# 173| 1: [Parameter] i -# 173| -1: [TypeMention] int -# 173| 1: [IntLiteral] 1 -# 174| 4: [BlockStmt] {...} -# 175| 0: [ReturnStmt] return ...; -# 175| 0: [ParameterAccess] access to parameter list -# 178| 7: [ExtensionMethod] SkipTwoInt -# 178| -1: [TypeMention] IEnumerable -# 178| 1: [TypeMention] int +# 174| 0: [Parameter] list +# 174| -1: [TypeMention] IEnumerable +# 174| 1: [TypeMention] T +# 174| 1: [Parameter] i +# 174| -1: [TypeMention] int +# 174| 1: [IntLiteral] 1 +# 175| 4: [BlockStmt] {...} +# 176| 0: [ReturnStmt] return ...; +# 176| 0: [ParameterAccess] access to parameter list +# 179| 7: [ExtensionMethod] SkipTwoInt +# 179| -1: [TypeMention] IEnumerable +# 179| 1: [TypeMention] int #-----| 2: (Parameters) -# 178| 0: [Parameter] list -# 178| -1: [TypeMention] IEnumerable -# 178| 1: [TypeMention] int -# 178| 1: [Parameter] i -# 178| -1: [TypeMention] int -# 178| 1: [IntLiteral] 1 -# 179| 4: [BlockStmt] {...} -# 180| 0: [ReturnStmt] return ...; -# 180| 0: [MethodCall] call to method SkipTwo -# 180| -1: [ParameterAccess] access to parameter list -# 180| 0: [ParameterAccess] access to parameter i +# 179| 0: [Parameter] list +# 179| -1: [TypeMention] IEnumerable +# 179| 1: [TypeMention] int +# 179| 1: [Parameter] i +# 179| -1: [TypeMention] int +# 179| 1: [IntLiteral] 1 +# 180| 4: [BlockStmt] {...} +# 181| 0: [ReturnStmt] return ...; +# 181| 0: [MethodCall] call to method SkipTwo +# 181| -1: [ParameterAccess] access to parameter list +# 181| 0: [ParameterAccess] access to parameter i +# 185| 9: [Class] TestCollidingMethods<> +#-----| 1: (Type parameters) +# 185| 0: [TypeParameter] T +# 187| 5: [Method] M +# 187| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 187| 0: [Parameter] p1 +# 187| -1: [TypeMention] T +# 187| 1: [Parameter] p2 +# 187| -1: [TypeMention] int +# 187| 4: [BlockStmt] {...} +# 188| 6: [Method] M +# 188| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 188| 0: [Parameter] p1 +# 188| -1: [TypeMention] int +# 188| 1: [Parameter] p2 +# 188| -1: [TypeMention] int +# 188| 4: [BlockStmt] {...} +# 190| 7: [Method] Calls +# 190| -1: [TypeMention] Void +# 191| 4: [BlockStmt] {...} +# 192| 0: [LocalVariableDeclStmt] ... ...; +# 192| 0: [LocalVariableDeclAndInitExpr] TestCollidingMethods x = ... +# 192| -1: [TypeMention] TestCollidingMethods +# 192| 0: [LocalVariableAccess] access to local variable x +# 192| 1: [ObjectCreation] object creation of type TestCollidingMethods +# 192| 0: [TypeMention] TestCollidingMethods +# 192| 1: [TypeMention] int +# 193| 1: [ExprStmt] ...; +# 193| 0: [MethodCall] call to method M +# 193| -1: [LocalVariableAccess] access to local variable x +# 193| 0: [IntLiteral] 1 +# 193| 1: [IntLiteral] 1 +# 195| 2: [LocalVariableDeclStmt] ... ...; +# 195| 0: [LocalVariableDeclAndInitExpr] TestCollidingMethods y = ... +# 195| -1: [TypeMention] TestCollidingMethods +# 195| 0: [LocalVariableAccess] access to local variable y +# 195| 1: [ObjectCreation] object creation of type TestCollidingMethods +# 195| 0: [TypeMention] TestCollidingMethods +# 195| 1: [TypeMention] double +# 196| 3: [ExprStmt] ...; +# 196| 0: [MethodCall] call to method M +# 196| -1: [LocalVariableAccess] access to local variable y +# 196| 0: [DoubleLiteral] 1 +# 196| 1: [IntLiteral] 1 +# 197| 4: [ExprStmt] ...; +# 197| 0: [MethodCall] call to method M +# 197| -1: [LocalVariableAccess] access to local variable y +# 197| 0: [IntLiteral] 1 +# 197| 1: [IntLiteral] 1 +# 200| 8: [Class] Nested +# 202| 4: [InstanceConstructor] Nested +#-----| 2: (Parameters) +# 202| 0: [Parameter] p1 +# 202| -1: [TypeMention] int +# 202| 4: [BlockStmt] {...} +# 203| 5: [InstanceConstructor] Nested +#-----| 2: (Parameters) +# 203| 0: [Parameter] p1 +# 203| -1: [TypeMention] T +# 204| 4: [BlockStmt] {...} +# 205| 0: [LocalVariableDeclStmt] ... ...; +# 205| 0: [LocalVariableDeclAndInitExpr] Nested x = ... +# 205| -1: [TypeMention] Nested +# 205| 0: [LocalVariableAccess] access to local variable x +# 205| 1: [ObjectCreation] object creation of type Nested +# 205| -1: [TypeMention] Nested +# 205| 1: [TypeMention] TestCollidingMethods +# 205| 1: [TypeMention] int +# 205| 0: [IntLiteral] 1 +# 206| 1: [LocalVariableDeclStmt] ... ...; +# 206| 0: [LocalVariableDeclAndInitExpr] Nested y = ... +# 206| -1: [TypeMention] Nested +# 206| 0: [LocalVariableAccess] access to local variable y +# 206| 1: [ObjectCreation] object creation of type Nested +# 206| -1: [TypeMention] Nested +# 206| 1: [TypeMention] TestCollidingMethods +# 206| 1: [TypeMention] double +# 206| 0: [DoubleLiteral] 1 +# 207| 2: [LocalVariableDeclStmt] ... ...; +# 207| 0: [LocalVariableDeclAndInitExpr] Nested z = ... +# 207| -1: [TypeMention] Nested +# 207| 0: [LocalVariableAccess] access to local variable z +# 207| 1: [ObjectCreation] object creation of type Nested +# 207| -1: [TypeMention] Nested +# 207| 1: [TypeMention] TestCollidingMethods +# 207| 1: [TypeMention] double +# 207| 0: [IntLiteral] 1 diff --git a/csharp/ql/test/library-tests/methods/methods.cs b/csharp/ql/test/library-tests/methods/methods.cs index f67676cad46..72e9b0409c0 100644 --- a/csharp/ql/test/library-tests/methods/methods.cs +++ b/csharp/ql/test/library-tests/methods/methods.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Methods { @@ -180,4 +181,31 @@ namespace Methods return list.SkipTwo(i); } } + + public class TestCollidingMethods + { + public void M(T p1, int p2) { } + public void M(int p1, int p2) { } + + public void Calls() + { + var x = new TestCollidingMethods(); + x.M(1, 1); + + var y = new TestCollidingMethods(); + y.M(1.0, 1); + y.M(1, 1); + } + + public class Nested + { + public Nested(int p1) { } + public Nested(T p1) + { + var x = new TestCollidingMethods.Nested(1); + var y = new TestCollidingMethods.Nested(1.0); + var z = new TestCollidingMethods.Nested(1); + } + } + } } From 3d60c146ad2cb31bb576cfd79085626e28d77c7a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 25 May 2021 13:40:30 +0200 Subject: [PATCH 127/272] C#: Base IDs for constructed methods on their unconstructed counterparts --- .../Entities/Constructor.cs | 9 ++++ .../Entities/Method.cs | 46 +++++++++++++------ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs index 3f31108b57e..e3f77d9407e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs @@ -146,6 +146,15 @@ namespace Semmle.Extraction.CSharp.Entities public override void WriteId(EscapingTextWriter trapFile) { + if (!SymbolEqualityComparer.Default.Equals(Symbol, Symbol.OriginalDefinition)) + { + trapFile.WriteSubId(ContainingType!); + trapFile.Write("."); + trapFile.WriteSubId(OriginalDefinition); + trapFile.Write(";constructor"); + return; + } + if (Symbol.IsStatic) trapFile.Write("static"); trapFile.WriteSubId(ContainingType!); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs index 12d0ce4cc10..e5822ccbf58 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs @@ -129,6 +129,30 @@ namespace Semmle.Extraction.CSharp.Entities /// private static void BuildMethodId(Method m, EscapingTextWriter trapFile) { + if (!SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition)) + { + if (!SymbolEqualityComparer.Default.Equals(m.Symbol, m.ConstructedFromSymbol)) + { + trapFile.WriteSubId(Create(m.Context, m.ConstructedFromSymbol)); + trapFile.Write('<'); + // Encode the nullability of the type arguments in the label. + // Type arguments with different nullability can result in + // a constructed method with different nullability of its parameters and return type, + // so we need to create a distinct database entity for it. + trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); }); + trapFile.Write('>'); + } + else + { + trapFile.WriteSubId(m.ContainingType!); + trapFile.Write("."); + trapFile.WriteSubId(m.OriginalDefinition); + } + + WritePostfix(m, trapFile); + return; + } + m.Symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write(" "); @@ -141,24 +165,16 @@ namespace Semmle.Extraction.CSharp.Entities if (m.Symbol.IsGenericMethod) { - if (SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition)) - { - trapFile.Write('`'); - trapFile.Write(m.Symbol.TypeParameters.Length); - } - else - { - trapFile.Write('<'); - // Encode the nullability of the type arguments in the label. - // Type arguments with different nullability can result in - // a constructed method with different nullability of its parameters and return type, - // so we need to create a distinct database entity for it. - trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); }); - trapFile.Write('>'); - } + trapFile.Write('`'); + trapFile.Write(m.Symbol.TypeParameters.Length); } AddParametersToId(m.Context, trapFile, m.Symbol); + WritePostfix(m, trapFile); + } + + private static void WritePostfix(Method m, EscapingTextWriter trapFile) + { switch (m.Symbol.MethodKind) { case MethodKind.PropertyGet: From 5a3a011b8e4b0b578f58b13f2e1ba7dce96c2d58 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 3 Jun 2021 11:17:01 +0200 Subject: [PATCH 128/272] Fix test results --- .../library-tests/methods/DB-CHECK.expected | 130 ------------------ .../library-tests/methods/Methods5.expected | 2 - .../methods/Parameters8.expected | 4 - 3 files changed, 136 deletions(-) delete mode 100644 csharp/ql/test/library-tests/methods/DB-CHECK.expected diff --git a/csharp/ql/test/library-tests/methods/DB-CHECK.expected b/csharp/ql/test/library-tests/methods/DB-CHECK.expected deleted file mode 100644 index 4a99289a434..00000000000 --- a/csharp/ql/test/library-tests/methods/DB-CHECK.expected +++ /dev/null @@ -1,130 +0,0 @@ -[INVALID_KEY] predicate methods(@method id, string name, @type declaring_type_id, @type_or_ref type_id, @method unbound_id): The key set {id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 4: -Tuple 1 in row 28: (828,"M",827,1087,813) -Tuple 2 in row 29: (828,"M",827,1087,1135) - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 827: @"(294)<(366)>;type". The ID may expand to @"{@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"{@";namespace"}.System;namespace"}.Int32;type"}>;type" - Relevant element: Full ID for 1087: @"(365);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"};typeRef" - Relevant element: Full ID for 813: @"(365) (294).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 827: @"(294)<(366)>;type". The ID may expand to @"{@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"{@";namespace"}.System;namespace"}.Int32;type"}>;type" - Relevant element: Full ID for 1087: @"(365);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"};typeRef" - Relevant element: Full ID for 1135: @"(365) (294).M((296) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@";namespace"}.Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" -[INVALID_KEY] predicate constructors(@constructor id, string name, @type declaring_type_id, @constructor unbound_id): The key set {id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 3: -Tuple 1 in row 14: (897,"Nested",830,332) -Tuple 2 in row 15: (897,"Nested",830,1143) - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 830: @"(827).Nested;type". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.Nested;type" - Relevant element: Full ID for 332: @"(297)((296) p1);constructor". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.Nested;type"}({@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 830: @"(827).Nested;type". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.Nested;type" - Relevant element: Full ID for 1143: @"(297)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" -[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {name, parent_id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 34: (1005,"p1",1083,0,0,828,1138) -Tuple 2 in row 35: (1005,"p1",1083,0,0,828,1348) - Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1138: @"(1135)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1348: @"(813)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" -[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {name, parent_id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 42: (1031,"p1",1083,0,0,897,335) -Tuple 2 in row 43: (1031,"p1",1083,0,0,897,1146) - Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 335: @"(332)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 1146: @"(1143)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" -[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {name, parent_id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 36: (1006,"p2",1083,1,0,828,1140) -Tuple 2 in row 37: (1006,"p2",1083,1,0,828,1350) - Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1140: @"(1135)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1350: @"(813)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" -[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {index, parent_id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 34: (1005,"p1",1083,0,0,828,1138) -Tuple 2 in row 35: (1005,"p1",1083,0,0,828,1348) - Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1138: @"(1135)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1348: @"(813)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" -[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {index, parent_id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 42: (1031,"p1",1083,0,0,897,335) -Tuple 2 in row 43: (1031,"p1",1083,0,0,897,1146) - Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 335: @"(332)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 1146: @"(1143)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" -[INVALID_KEY_SET] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {index, parent_id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 36: (1006,"p2",1083,1,0,828,1140) -Tuple 2 in row 37: (1006,"p2",1083,1,0,828,1350) - Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1140: @"(1135)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1350: @"(813)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" -[INVALID_KEY] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 34: (1005,"p1",1083,0,0,828,1138) -Tuple 2 in row 35: (1005,"p1",1083,0,0,828,1348) - Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1138: @"(1135)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1005: @"(828)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1348: @"(813)_0;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_0;parameter" -[INVALID_KEY] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 36: (1006,"p2",1083,1,0,828,1140) -Tuple 2 in row 37: (1006,"p2",1083,1,0,828,1350) - Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1140: @"(1135)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1006: @"(828)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 828: @"(365) (827).M((366) p1,(366) p2);method". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Void;type"} {@"{@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}<{@"{@"(111).System;namespace"}.Int32;type"}>;type"}.M({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1,{@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p2);method" - Relevant element: Full ID for 1350: @"(813)_1;parameter". The ID may expand to @"{@"{@"{@"(111).System;namespace"}.Void;type"} {@"{@"(111).Methods;namespace"}.TestCollidingMethods`1;type"}.M({@"{@"(111).System;namespace"}.Int32;type"} p1,{@"{@"(111).System;namespace"}.Int32;type"} p2);method"}_1;parameter" -[INVALID_KEY] predicate params(@parameter id, string name, @type_or_ref type_id, int index, int mode, @parameterizable parent_id, @parameter unbound_id): The key set {id} does not functionally determine all fields. -Here is a pair of tuples that agree on the key set but differ at index 6: -Tuple 1 in row 42: (1031,"p1",1083,0,0,897,335) -Tuple 2 in row 43: (1031,"p1",1083,0,0,897,1146) - Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 335: @"(332)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(130).TestCollidingMethods`1;type"}_0;typeparameter"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1031: @"(897)_0;parameter". The ID may expand to @"{@"{@"{@"(294)<(366)>;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" - Relevant element: Full ID for 1083: @"(366);typeRef". The ID may expand to @"{@"{@"{@";namespace"}.System;namespace"}.Int32;type"};typeRef" - Relevant element: Full ID for 897: @"(830)((366) p1);constructor". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}<{@"(112).Int32;type"}>;type"}.Nested;type"}({@"{@"{@";namespace"}.System;namespace"}.Int32;type"} p1);constructor" - Relevant element: Full ID for 1146: @"(1143)_0;parameter". The ID may expand to @"{@"{@"{@"(130).TestCollidingMethods`1;type"}.Nested;type"}({@"{@"(111).System;namespace"}.Int32;type"} p1);constructor"}_0;parameter" diff --git a/csharp/ql/test/library-tests/methods/Methods5.expected b/csharp/ql/test/library-tests/methods/Methods5.expected index 03638800b01..01beaa41f6e 100644 --- a/csharp/ql/test/library-tests/methods/Methods5.expected +++ b/csharp/ql/test/library-tests/methods/Methods5.expected @@ -21,10 +21,8 @@ | methods.cs:125:21:125:24 | Main | methods.cs:110:27:110:34 | Slice | methods.cs:122:18:122:31 | TestExtensions | | methods.cs:179:67:179:76 | SkipTwoInt | methods.cs:174:65:174:74 | SkipTwo | methods.cs:167:18:167:47 | TestDefaultExtensionParameters | | methods.cs:190:21:190:25 | Calls | methods.cs:187:21:187:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | -| methods.cs:190:21:190:25 | Calls | methods.cs:187:21:187:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | | methods.cs:190:21:190:25 | Calls | methods.cs:188:21:188:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | | methods.cs:190:21:190:25 | Calls | methods.cs:188:21:188:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> | | methods.cs:203:20:203:25 | Nested | methods.cs:202:20:202:25 | Nested | methods.cs:200:22:200:27 | Nested | | methods.cs:203:20:203:25 | Nested | methods.cs:202:20:202:25 | Nested | methods.cs:200:22:200:27 | Nested | | methods.cs:203:20:203:25 | Nested | methods.cs:203:20:203:25 | Nested | methods.cs:200:22:200:27 | Nested | -| methods.cs:203:20:203:25 | Nested | methods.cs:203:20:203:25 | Nested | methods.cs:200:22:200:27 | Nested | diff --git a/csharp/ql/test/library-tests/methods/Parameters8.expected b/csharp/ql/test/library-tests/methods/Parameters8.expected index 6efd343a538..62c4d495009 100644 --- a/csharp/ql/test/library-tests/methods/Parameters8.expected +++ b/csharp/ql/test/library-tests/methods/Parameters8.expected @@ -47,10 +47,6 @@ | methods.cs:187:21:187:21 | M | methods.cs:187:33:187:34 | p2 | | methods.cs:187:21:187:21 | M | methods.cs:187:33:187:34 | p2 | | methods.cs:187:21:187:21 | M | methods.cs:187:33:187:34 | p2 | -| methods.cs:187:21:187:21 | M | methods.cs:188:27:188:28 | p1 | -| methods.cs:187:21:187:21 | M | methods.cs:188:35:188:36 | p2 | -| methods.cs:188:21:188:21 | M | methods.cs:187:25:187:26 | p1 | -| methods.cs:188:21:188:21 | M | methods.cs:187:33:187:34 | p2 | | methods.cs:188:21:188:21 | M | methods.cs:188:27:188:28 | p1 | | methods.cs:188:21:188:21 | M | methods.cs:188:27:188:28 | p1 | | methods.cs:188:21:188:21 | M | methods.cs:188:27:188:28 | p1 | From 9372e3b284188503b91666a128c6da25fc29a36b Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 3 Jun 2021 11:23:28 +0200 Subject: [PATCH 129/272] Python: Add aiohttp.web change-note --- python/change-notes/2021-06-03-aiohttp-webserver-modeling.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 python/change-notes/2021-06-03-aiohttp-webserver-modeling.md diff --git a/python/change-notes/2021-06-03-aiohttp-webserver-modeling.md b/python/change-notes/2021-06-03-aiohttp-webserver-modeling.md new file mode 100644 index 00000000000..a62a9c4b75e --- /dev/null +++ b/python/change-notes/2021-06-03-aiohttp-webserver-modeling.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added modeling of sources/sinks when using `aiohttp.web` to create web servers. From 2e851cd5f04be353d0f1b94821d39719b554d900 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 3 Jun 2021 11:38:15 +0200 Subject: [PATCH 130/272] Python: Improve `yarl.URL` modeling --- .../ql/src/semmle/python/frameworks/Yarl.qll | 11 +++ .../frameworks/aiohttp/taint_test.py | 67 +------------------ .../frameworks/yarl/ConceptsTest.expected | 0 .../frameworks/yarl/ConceptsTest.ql | 2 + .../frameworks/yarl/InlineTaintTest.expected | 3 + .../frameworks/yarl/InlineTaintTest.ql | 1 + .../library-tests/frameworks/yarl/options | 1 + .../frameworks/yarl/taint_test.py | 64 ++++++++++++++++++ 8 files changed, 85 insertions(+), 64 deletions(-) create mode 100644 python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/yarl/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected create mode 100644 python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql create mode 100644 python/ql/test/library-tests/frameworks/yarl/options create mode 100644 python/ql/test/library-tests/frameworks/yarl/taint_test.py diff --git a/python/ql/src/semmle/python/frameworks/Yarl.qll b/python/ql/src/semmle/python/frameworks/Yarl.qll index a998d8e0ca1..b91a407832f 100644 --- a/python/ql/src/semmle/python/frameworks/Yarl.qll +++ b/python/ql/src/semmle/python/frameworks/Yarl.qll @@ -34,6 +34,11 @@ module Yarl { */ abstract class InstanceSource extends DataFlow::LocalSourceNode { } + /** A direct instantiation of `yarl.URL`. */ + private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { + ClassInstantiation() { this = API::moduleImport("yarl").getMember("URL").getACall() } + } + /** Gets a reference to an instance of `yarl.URL`. */ private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { t.start() and @@ -52,6 +57,12 @@ module Yarl { */ class YarlUrlAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // class instantiation + exists(ClassInstantiation call | + nodeFrom in [call.getArg(0), call.getArgByName("val")] and + nodeTo = call + ) + or // Methods // // TODO: When we have tools that make it easy, model these properly to handle diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index dcf21f92687..1b70879d6d3 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -5,11 +5,12 @@ async def test_taint(request: web.Request): # $ requestHandler ensure_tainted( request, # $ tainted - # yarl.URL instances + # yarl.URL instances, see tests under `yarl` framework tests # https://yarl.readthedocs.io/en/stable/api.html#yarl.URL - # see below request.url, # $ tainted + request.url.human_repr(), # $ tainted request.rel_url, # $ tainted + request.rel_url.human_repr(), # $ tainted request.forwarded, # $ tainted @@ -130,68 +131,6 @@ async def test_taint(request: web.Request): # $ requestHandler request.config_dict, ) - # TODO: Should have a better way to capture that we in fact _do_ model this as a - # an instance of the right class, and have the actual taint_test for that in a - # different file! - import yarl - - ensure_tainted( - # see https://yarl.readthedocs.io/en/stable/api.html#yarl.URL - request.url.user, # $ tainted - request.url.raw_user, # $ tainted - - request.url.password, # $ tainted - request.url.raw_password, # $ tainted - - request.url.host, # $ tainted - request.url.raw_host, # $ tainted - - request.url.port, # $ tainted - request.url.explicit_port, # $ tainted - - request.url.authority, # $ tainted - request.url.raw_authority, # $ tainted - - request.url.path, # $ tainted - request.url.raw_path, # $ tainted - - request.url.path_qs, # $ tainted - request.url.raw_path_qs, # $ tainted - - request.url.query_string, # $ tainted - request.url.raw_query_string, # $ tainted - - request.url.fragment, # $ tainted - request.url.raw_fragment, # $ tainted - - request.url.parts, # $ tainted - request.url.raw_parts, # $ tainted - - request.url.name, # $ tainted - request.url.raw_name, # $ tainted - - # multidict.MultiDictProxy[str] - request.url.query, # $ tainted - request.url.query.getone("key"), # $ tainted - - request.url.with_scheme("foo"), # $ tainted - request.url.with_user("foo"), # $ tainted - request.url.with_password("foo"), # $ tainted - request.url.with_host("foo"), # $ tainted - request.url.with_port("foo"), # $ tainted - request.url.with_path("foo"), # $ tainted - request.url.with_query({"foo": 42}), # $ tainted - request.url.with_query(foo=42), # $ tainted - request.url.update_query({"foo": 42}), # $ tainted - request.url.update_query(foo=42), # $ tainted - request.url.with_fragment("foo"), # $ tainted - request.url.with_name("foo"), # $ tainted - - request.url.join(yarl.URL("wat.html")), # $ tainted - - request.url.human_repr(), # $ tainted - ) - class TaintTestClass(web.View): def get(self): # $ requestHandler diff --git a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.ql new file mode 100644 index 00000000000..b557a0bccb6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected new file mode 100644 index 00000000000..79d760d87f4 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected @@ -0,0 +1,3 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +failures diff --git a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql new file mode 100644 index 00000000000..027ad8667be --- /dev/null +++ b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql @@ -0,0 +1 @@ +import experimental.meta.InlineTaintTest diff --git a/python/ql/test/library-tests/frameworks/yarl/options b/python/ql/test/library-tests/frameworks/yarl/options new file mode 100644 index 00000000000..cfef58cf2b2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/yarl/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --lang=3 diff --git a/python/ql/test/library-tests/frameworks/yarl/taint_test.py b/python/ql/test/library-tests/frameworks/yarl/taint_test.py new file mode 100644 index 00000000000..9fa012a9f2f --- /dev/null +++ b/python/ql/test/library-tests/frameworks/yarl/taint_test.py @@ -0,0 +1,64 @@ +import yarl + + +url = yarl.URL(TAINTED_STRING) + + +ensure_tainted( + url, # $ tainted + + # see https://yarl.readthedocs.io/en/stable/api.html#yarl.URL + url.user, # $ tainted + url.raw_user, # $ tainted + + url.password, # $ tainted + url.raw_password, # $ tainted + + url.host, # $ tainted + url.raw_host, # $ tainted + + url.port, # $ tainted + url.explicit_port, # $ tainted + + url.authority, # $ tainted + url.raw_authority, # $ tainted + + url.path, # $ tainted + url.raw_path, # $ tainted + + url.path_qs, # $ tainted + url.raw_path_qs, # $ tainted + + url.query_string, # $ tainted + url.raw_query_string, # $ tainted + + url.fragment, # $ tainted + url.raw_fragment, # $ tainted + + url.parts, # $ tainted + url.raw_parts, # $ tainted + + url.name, # $ tainted + url.raw_name, # $ tainted + + # multidict.MultiDictProxy[str] + url.query, # $ tainted + url.query.getone("key"), # $ tainted + + url.with_scheme("foo"), # $ tainted + url.with_user("foo"), # $ tainted + url.with_password("foo"), # $ tainted + url.with_host("foo"), # $ tainted + url.with_port("foo"), # $ tainted + url.with_path("foo"), # $ tainted + url.with_query({"foo": 42}), # $ tainted + url.with_query(foo=42), # $ tainted + url.update_query({"foo": 42}), # $ tainted + url.update_query(foo=42), # $ tainted + url.with_fragment("foo"), # $ tainted + url.with_name("foo"), # $ tainted + + url.join(yarl.URL("wat.html")), # $ tainted + + url.human_repr(), # $ tainted +) From e9acea8643c3ccac3568134c938fcb6509c942d5 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 3 Jun 2021 11:50:49 +0200 Subject: [PATCH 131/272] Python: Improve `multidict` modeling --- .../semmle/python/frameworks/Multidict.qll | 20 ++++++++- .../frameworks/aiohttp/taint_test.py | 26 ++---------- .../multidict/ConceptsTest.expected | 0 .../frameworks/multidict/ConceptsTest.ql | 2 + .../multidict/InlineTaintTest.expected | 3 ++ .../frameworks/multidict/InlineTaintTest.ql | 1 + .../frameworks/multidict/options | 1 + .../frameworks/multidict/taint_test.py | 41 +++++++++++++++++++ 8 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/multidict/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected create mode 100644 python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql create mode 100644 python/ql/test/library-tests/frameworks/multidict/options create mode 100644 python/ql/test/library-tests/frameworks/multidict/taint_test.py diff --git a/python/ql/src/semmle/python/frameworks/Multidict.qll b/python/ql/src/semmle/python/frameworks/Multidict.qll index 7a2c2bf0751..6a04bd2b8d2 100644 --- a/python/ql/src/semmle/python/frameworks/Multidict.qll +++ b/python/ql/src/semmle/python/frameworks/Multidict.qll @@ -24,6 +24,11 @@ module Multidict { * See https://multidict.readthedocs.io/en/stable/multidict.html#multidictproxy */ module MultiDictProxy { + /** Gets a reference to a `MultiDictProxy` class. */ + API::Node classRef() { + result = API::moduleImport("multidict").getMember(["MultiDictProxy", "CIMultiDictProxy"]) + } + /** * A source of instances of `multidict.MultiDictProxy`, extend this class to model * new instances. @@ -37,7 +42,12 @@ module Multidict { */ abstract class InstanceSource extends DataFlow::LocalSourceNode { } - /** Gets a reference to an instance of `multidict.MultiDictProxy`. */ + /** A direct instantiation of a `MultiDictProxy` class. */ + private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { + ClassInstantiation() { this = classRef().getACall() } + } + + /** Gets a reference to an instance of a `MultiDictProxy` class. */ private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) { t.start() and result instanceof InstanceSource @@ -45,7 +55,7 @@ module Multidict { exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) } - /** Gets a reference to an instance of `multidict.MultiDictProxy`. */ + /** Gets a reference to an instance of a `MultiDictProxy` class. */ DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } /** @@ -55,6 +65,12 @@ module Multidict { */ class MultiDictProxyAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // class instantiation + exists(ClassInstantiation call | + nodeFrom = call.getArg(0) and + nodeTo = call + ) + or // Methods // // TODO: When we have tools that make it easy, model these properly to handle diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 1b70879d6d3..2bc3e529402 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -5,8 +5,7 @@ async def test_taint(request: web.Request): # $ requestHandler ensure_tainted( request, # $ tainted - # yarl.URL instances, see tests under `yarl` framework tests - # https://yarl.readthedocs.io/en/stable/api.html#yarl.URL + # yarl.URL (see `yarl` framework tests) request.url, # $ tainted request.url.human_repr(), # $ tainted request.rel_url, # $ tainted @@ -25,28 +24,11 @@ async def test_taint(request: web.Request): # $ requestHandler request.match_info["key"], # $ tainted request.match_info.get("key"), # $ tainted - # multidict.MultiDictProxy[str] - # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.MultiDictProxy - # TODO: Should have a better way to capture that we in fact _do_ model this as a - # an instance of the right class, and have the actual taint_test for that in a - # different file! + # multidict.MultiDictProxy[str] (see `multidict` framework tests) request.query, # $ tainted - request.query["key"], # $ tainted - request.query.get("key"), # $ tainted request.query.getone("key"), # $ tainted - request.query.getall("key"), # $ tainted - request.query.keys(), # $ MISSING: tainted - request.query.values(), # $ tainted - request.query.items(), # $ tainted - request.query.copy(), # $ tainted - list(request.query), # $ tainted - iter(request.query), # $ tainted - # multidict.CIMultiDictProxy[str] - # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.CIMultiDictProxy - # TODO: Should have a better way to capture that we in fact _do_ model this as a - # an instance of the right class, and have the actual taint_test for that in a - # different file! + # multidict.CIMultiDictProxy[str] (see `multidict` framework tests) request.headers, # $ tainted request.headers.getone("key"), # $ tainted @@ -99,7 +81,7 @@ async def test_taint(request: web.Request): # $ requestHandler # aiohttp.multipart.MultipartReader await request.multipart(), # $ tainted - # multidict.MultiDictProxy[str] + # multidict.MultiDictProxy[str] (see `multidict` framework tests) await request.post(), # $ tainted (await request.post()).getone("key"), # $ MISSING: tainted ) diff --git a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.ql new file mode 100644 index 00000000000..b557a0bccb6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected new file mode 100644 index 00000000000..79d760d87f4 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected @@ -0,0 +1,3 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +failures diff --git a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql new file mode 100644 index 00000000000..027ad8667be --- /dev/null +++ b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql @@ -0,0 +1 @@ +import experimental.meta.InlineTaintTest diff --git a/python/ql/test/library-tests/frameworks/multidict/options b/python/ql/test/library-tests/frameworks/multidict/options new file mode 100644 index 00000000000..cfef58cf2b2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/multidict/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --lang=3 diff --git a/python/ql/test/library-tests/frameworks/multidict/taint_test.py b/python/ql/test/library-tests/frameworks/multidict/taint_test.py new file mode 100644 index 00000000000..8fbac79888f --- /dev/null +++ b/python/ql/test/library-tests/frameworks/multidict/taint_test.py @@ -0,0 +1,41 @@ +import multidict + +# TODO: This is an invalid MultiDictProxy construction... but for the purpose of +# taint-test, this should be good enough. +mdp = multidict.MultiDictProxy(TAINTED_STRING) + +ensure_tainted( + # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.MultiDictProxy + + mdp, # $ tainted + mdp["key"], # $ tainted + mdp.get("key"), # $ tainted + mdp.getone("key"), # $ tainted + mdp.getall("key"), # $ tainted + mdp.keys(), # $ MISSING: tainted + mdp.values(), # $ tainted + mdp.items(), # $ tainted + mdp.copy(), # $ tainted + list(mdp), # $ tainted + iter(mdp), # $ tainted +) + +# TODO: This is an invalid CIMultiDictProxy construction... but for the purpose of +# taint-test, this should be good enough. +ci_mdp = multidict.CIMultiDictProxy(TAINTED_STRING) + +ensure_tainted( + # see https://multidict.readthedocs.io/en/stable/multidict.html#multidict.CIMultiDictProxy + + ci_mdp, # $ tainted + ci_mdp["key"], # $ tainted + ci_mdp.get("key"), # $ tainted + ci_mdp.getone("key"), # $ tainted + ci_mdp.getall("key"), # $ tainted + ci_mdp.keys(), # $ MISSING: tainted + ci_mdp.values(), # $ tainted + ci_mdp.items(), # $ tainted + ci_mdp.copy(), # $ tainted + list(ci_mdp), # $ tainted + iter(ci_mdp), # $ tainted +) From 793e3db085b34191836c2cf31661f70243e2cb1e Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 3 Jun 2021 11:54:05 +0200 Subject: [PATCH 132/272] C#: Change compilation settings to include all non-public symbols --- .../Semmle.Extraction.CSharp/Extractor/Extractor.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index 179d1f14de5..1dd6d817b01 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -416,9 +416,10 @@ namespace Semmle.Extraction.CSharp compilerArguments.CompilationName, syntaxTrees, references, - compilerArguments.CompilationOptions. - WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default). - WithStrongNameProvider(new DesktopStrongNameProvider(compilerArguments.KeyFileSearchPaths)) + compilerArguments.CompilationOptions + .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) + .WithStrongNameProvider(new DesktopStrongNameProvider(compilerArguments.KeyFileSearchPaths)) + .WithMetadataImportOptions(MetadataImportOptions.All) ); }, (compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation), From 79bef11cf7cc888fb828f750216b41b87320f7d3 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 3 Jun 2021 12:10:29 +0200 Subject: [PATCH 133/272] Python: Use "new" SensitiveDataHeuristics --- .../dataflow/new/SensitiveDataSources.qll | 21 +++++++++---------- ...WeakSensitiveDataHashingCustomizations.qll | 12 ++++++----- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/python/ql/src/semmle/python/dataflow/new/SensitiveDataSources.qll b/python/ql/src/semmle/python/dataflow/new/SensitiveDataSources.qll index 42be7aacfe9..ea3f135ed98 100644 --- a/python/ql/src/semmle/python/dataflow/new/SensitiveDataSources.qll +++ b/python/ql/src/semmle/python/dataflow/new/SensitiveDataSources.qll @@ -9,6 +9,12 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.Frameworks private import semmle.python.Concepts private import semmle.python.security.SensitiveData as OldSensitiveData +private import semmle.python.security.internal.SensitiveDataHeuristics as SensitiveDataHeuristics + +// We export these explicitly, so we don't also export the `HeuristicNames` module. +class SensitiveDataClassification = SensitiveDataHeuristics::SensitiveDataClassification; + +module SensitiveDataClassification = SensitiveDataHeuristics::SensitiveDataClassification; /** * A data flow source of sensitive data, such as secrets, certificates, or passwords. @@ -22,13 +28,9 @@ class SensitiveDataSource extends DataFlow::Node { SensitiveDataSource() { this = range } /** - * INTERNAL: Do not use. - * - * This will be rewritten to have better types soon, and therefore should only be used internally until then. - * * Gets the classification of the sensitive data. */ - string getClassification() { result = range.getClassification() } + SensitiveDataClassification getClassification() { result = range.getClassification() } } /** Provides a class for modeling new sources of sensitive data, such as secrets, certificates, or passwords. */ @@ -41,22 +43,19 @@ module SensitiveDataSource { */ abstract class Range extends DataFlow::Node { /** - * INTERNAL: Do not use. - * - * This will be rewritten to have better types soon, and therefore should only be used internally until then. - * * Gets the classification of the sensitive data. */ - abstract string getClassification(); + abstract SensitiveDataClassification getClassification(); } } +// TODO: rewrite this to not rely on the old points-to implementation private class PortOfOldModeling extends SensitiveDataSource::Range { OldSensitiveData::SensitiveData::Source oldSensitiveSource; PortOfOldModeling() { this.asCfgNode() = oldSensitiveSource } - override string getClassification() { + override SensitiveDataClassification getClassification() { exists(OldSensitiveData::SensitiveData classification | oldSensitiveSource.isSourceOf(classification) | diff --git a/python/ql/src/semmle/python/security/dataflow/WeakSensitiveDataHashingCustomizations.qll b/python/ql/src/semmle/python/security/dataflow/WeakSensitiveDataHashingCustomizations.qll index 8b9d6f4e83f..c867c1e9924 100644 --- a/python/ql/src/semmle/python/security/dataflow/WeakSensitiveDataHashingCustomizations.qll +++ b/python/ql/src/semmle/python/security/dataflow/WeakSensitiveDataHashingCustomizations.qll @@ -52,7 +52,9 @@ module NormalHashFunction { * A source of sensitive data, considered as a flow source. */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { - override string getClassification() { result = SensitiveDataSource.super.getClassification() } + override SensitiveDataClassification getClassification() { + result = SensitiveDataSource.super.getClassification() + } } /** The input to a hashing operation using a weak algorithm, considered as a flow sink. */ @@ -120,12 +122,12 @@ module ComputationallyExpensiveHashFunction { */ class PasswordSourceAsSource extends Source, SensitiveDataSource { PasswordSourceAsSource() { - // TODO: once https://github.com/github/codeql/pull/5739 has been merged, - // don't use hardcoded value anymore - SensitiveDataSource.super.getClassification() = "password" + SensitiveDataSource.super.getClassification() = SensitiveDataClassification::password() } - override string getClassification() { result = SensitiveDataSource.super.getClassification() } + override SensitiveDataClassification getClassification() { + result = SensitiveDataSource.super.getClassification() + } } /** From e543c6c6659322e41cae74868b26d34f921f4c1d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 3 Jun 2021 12:23:05 +0200 Subject: [PATCH 134/272] add a `js/client-side-unvalidated-url-redirection` sink for the `history` library --- .../ClientSideUrlRedirectCustomizations.qll | 15 +++++++++++++++ .../ClientSideUrlRedirect.expected | 12 ++++++++++++ .../CWE-601/ClientSideUrlRedirect/tst13.js | 7 +++++++ 3 files changed, 34 insertions(+) diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index ed182831eea..9bca989e984 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -191,6 +191,21 @@ module ClientSideUrlRedirect { } } + /** + * A write to the location using the [history](https://npmjs.com/package/history) library + */ + class HistoryWriteUrlSink extends ScriptUrlSink { + HistoryWriteUrlSink() { + this = + API::moduleImport("history") + .getMember(["createBrowserHistory", "createHashHistory"]) + .getReturn() + .getMember(["push", "replace"]) + .getACall() + .getArgument(0) + } + } + /** * A call to change the current url with a Next.js router. */ diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index e835fa95acc..a7148512587 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -129,6 +129,12 @@ nodes | tst13.js:52:34:52:34 | e | | tst13.js:53:28:53:28 | e | | tst13.js:53:28:53:28 | e | +| tst13.js:59:9:59:52 | payload | +| tst13.js:59:19:59:42 | documen ... .search | +| tst13.js:59:19:59:42 | documen ... .search | +| tst13.js:59:19:59:52 | documen ... bstr(1) | +| tst13.js:61:18:61:24 | payload | +| tst13.js:61:18:61:24 | payload | | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | @@ -306,6 +312,11 @@ edges | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | +| tst13.js:59:9:59:52 | payload | tst13.js:61:18:61:24 | payload | +| tst13.js:59:9:59:52 | payload | tst13.js:61:18:61:24 | payload | +| tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | +| tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | +| tst13.js:59:19:59:52 | documen ... bstr(1) | tst13.js:59:9:59:52 | payload | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | @@ -397,6 +408,7 @@ edges | tst13.js:44:14:44:20 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:44:14:44:20 | payload | Untrusted URL redirection due to $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | | tst13.js:50:23:50:23 | e | tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | Untrusted URL redirection due to $@. | tst13.js:49:32:49:32 | e | user-provided value | | tst13.js:53:28:53:28 | e | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | Untrusted URL redirection due to $@. | tst13.js:52:34:52:34 | e | user-provided value | +| tst13.js:61:18:61:24 | payload | tst13.js:59:19:59:42 | documen ... .search | tst13.js:61:18:61:24 | payload | Untrusted URL redirection due to $@. | tst13.js:59:19:59:42 | documen ... .search | user-provided value | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:63 | document.location | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:63 | document.location | user-provided value | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:68 | documen ... on.href | user-provided value | | tst.js:6:20:6:59 | indirec ... ref)[1] | tst.js:6:34:6:50 | document.location | tst.js:6:20:6:59 | indirec ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:6:34:6:50 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js index 7a71cf06c08..873001ca626 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js @@ -53,3 +53,10 @@ function foo() { self.importScripts(e); // NOT OK } })(); + +const history = require('history').createBrowserHistory(); +function bar() { + var payload = document.location.search.substr(1); + + history.push(payload); // NOT OK +} \ No newline at end of file From 608a0314df72762f48f5da40351fd8952d7e4dd5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 3 Jun 2021 12:33:25 +0200 Subject: [PATCH 135/272] add location reads from the `history` libary as client-side remote flow --- .../javascript/security/dataflow/DOM.qll | 27 +++++++++++++++++++ .../ClientSideUrlRedirect.expected | 12 +++++++++ .../CWE-601/ClientSideUrlRedirect/tst13.js | 8 +++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll b/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll index 204f04e9c52..42f5924f6aa 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll @@ -272,3 +272,30 @@ private class WindowLocationFlowSource extends ClientSideRemoteFlowSource { override ClientSideRemoteFlowKind getKind() { result = kind } } + +/** + * A user-controlled location value read from the [history](http://npmjs.org/package/history) library. + */ +private class HistoryLibaryRemoteFlow extends ClientSideRemoteFlowSource { + ClientSideRemoteFlowKind kind; + + HistoryLibaryRemoteFlow() { + exists(API::Node loc | + loc = + API::moduleImport("history") + .getMember(["createBrowserHistory", "createHashHistory"]) + .getReturn() + .getMember("location") + | + this = loc.getMember("hash").getAnImmediateUse() and kind.isFragment() + or + this = loc.getMember("pathname").getAnImmediateUse() and kind.isPath() + or + this = loc.getMember("search").getAnImmediateUse() and kind.isQuery() + ) + } + + override string getSourceType() { result = "Window location" } + + override ClientSideRemoteFlowKind getKind() { result = kind } +} diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index a7148512587..d3edd76979b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -135,6 +135,12 @@ nodes | tst13.js:59:19:59:52 | documen ... bstr(1) | | tst13.js:61:18:61:24 | payload | | tst13.js:61:18:61:24 | payload | +| tst13.js:65:9:65:49 | payload | +| tst13.js:65:19:65:39 | history ... on.hash | +| tst13.js:65:19:65:39 | history ... on.hash | +| tst13.js:65:19:65:49 | history ... bstr(1) | +| tst13.js:67:21:67:27 | payload | +| tst13.js:67:21:67:27 | payload | | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | @@ -317,6 +323,11 @@ edges | tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | | tst13.js:59:19:59:42 | documen ... .search | tst13.js:59:19:59:52 | documen ... bstr(1) | | tst13.js:59:19:59:52 | documen ... bstr(1) | tst13.js:59:9:59:52 | payload | +| tst13.js:65:9:65:49 | payload | tst13.js:67:21:67:27 | payload | +| tst13.js:65:9:65:49 | payload | tst13.js:67:21:67:27 | payload | +| tst13.js:65:19:65:39 | history ... on.hash | tst13.js:65:19:65:49 | history ... bstr(1) | +| tst13.js:65:19:65:39 | history ... on.hash | tst13.js:65:19:65:49 | history ... bstr(1) | +| tst13.js:65:19:65:49 | history ... bstr(1) | tst13.js:65:9:65:49 | payload | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | @@ -409,6 +420,7 @@ edges | tst13.js:50:23:50:23 | e | tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | Untrusted URL redirection due to $@. | tst13.js:49:32:49:32 | e | user-provided value | | tst13.js:53:28:53:28 | e | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | Untrusted URL redirection due to $@. | tst13.js:52:34:52:34 | e | user-provided value | | tst13.js:61:18:61:24 | payload | tst13.js:59:19:59:42 | documen ... .search | tst13.js:61:18:61:24 | payload | Untrusted URL redirection due to $@. | tst13.js:59:19:59:42 | documen ... .search | user-provided value | +| tst13.js:67:21:67:27 | payload | tst13.js:65:19:65:39 | history ... on.hash | tst13.js:67:21:67:27 | payload | Untrusted URL redirection due to $@. | tst13.js:65:19:65:39 | history ... on.hash | user-provided value | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:63 | document.location | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:63 | document.location | user-provided value | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:68 | documen ... on.href | user-provided value | | tst.js:6:20:6:59 | indirec ... ref)[1] | tst.js:6:34:6:50 | document.location | tst.js:6:20:6:59 | indirec ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:6:34:6:50 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js index 873001ca626..63956a651a2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js @@ -54,9 +54,15 @@ function foo() { } })(); -const history = require('history').createBrowserHistory(); function bar() { + const history = require('history').createBrowserHistory(); var payload = document.location.search.substr(1); history.push(payload); // NOT OK +} +function baz() { + const history = require('history').createHashHistory(); + var payload = history.location.hash.substr(1); + + history.replace(payload); // NOT OK } \ No newline at end of file From d30f53a21ab199a8dbfeb9c99e6bab5d6584086c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 3 Jun 2021 12:35:39 +0200 Subject: [PATCH 136/272] add change note --- javascript/change-notes/2021-06-03-history.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/change-notes/2021-06-03-history.md diff --git a/javascript/change-notes/2021-06-03-history.md b/javascript/change-notes/2021-06-03-history.md new file mode 100644 index 00000000000..da5054a2630 --- /dev/null +++ b/javascript/change-notes/2021-06-03-history.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* Taint sources and sinks from the [history](https://npmjs.com/package/history) library are now recognized. + Affected packages are + [history](https://www.npmjs.com/package/history) \ No newline at end of file From 1ce7c631ffacb593c8ae75ea521b10b3f11abce6 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 3 Jun 2021 13:01:42 +0200 Subject: [PATCH 137/272] Fix failing tests --- .../conversion/reftype/RefType.expected | 9 +++ .../csharp8/UnmanagedGenericStructs.ql | 2 +- .../dataflow/global/GetAnOutNode.expected | 6 ++ .../dataflow/library/FlowSummaries.expected | 70 +++++++++++++++++++ .../ql/test/library-tests/methods/Methods1.ql | 3 +- .../Stubs/MinimalStubsFromSource.expected | 2 +- 6 files changed, 89 insertions(+), 3 deletions(-) diff --git a/csharp/ql/test/library-tests/conversion/reftype/RefType.expected b/csharp/ql/test/library-tests/conversion/reftype/RefType.expected index cdcfcf78f96..88f34c17293 100644 --- a/csharp/ql/test/library-tests/conversion/reftype/RefType.expected +++ b/csharp/ql/test/library-tests/conversion/reftype/RefType.expected @@ -1,5 +1,7 @@ | Byte[] | Object | | Byte[] | dynamic | +| Byte[][] | Object | +| Byte[][] | dynamic | | C1 | Object | | C1 | dynamic | | C1[] | ICollection | @@ -183,6 +185,8 @@ | IReadOnlyList | dynamic | | Int16[] | Object | | Int16[] | dynamic | +| Int32[,] | Object | +| Int32[,] | dynamic | | Int32[] | Object | | Int32[] | dynamic | | Int64[] | Object | @@ -221,12 +225,15 @@ | T5 | C1 | | T5 | Object | | T5 | dynamic | +| UInt16[][] | Object | +| UInt16[][] | dynamic | | UInt32[] | Object | | UInt32[] | dynamic | | UInt64[] | Object | | UInt64[] | dynamic | | dynamic | Object | | null | Byte[] | +| null | Byte[][] | | null | C1 | | null | C1[] | | null | C2 | @@ -279,6 +286,7 @@ | null | IReadOnlyList | | null | IReadOnlyList | | null | Int16[] | +| null | Int32[,] | | null | Int32[] | | null | Int64[] | | null | Object | @@ -289,6 +297,7 @@ | null | T4 | | null | T4[] | | null | T5 | +| null | UInt16[][] | | null | UInt32[] | | null | UInt64[] | | null | dynamic | diff --git a/csharp/ql/test/library-tests/csharp8/UnmanagedGenericStructs.ql b/csharp/ql/test/library-tests/csharp8/UnmanagedGenericStructs.ql index 316e9458ae6..640454a71f9 100644 --- a/csharp/ql/test/library-tests/csharp8/UnmanagedGenericStructs.ql +++ b/csharp/ql/test/library-tests/csharp8/UnmanagedGenericStructs.ql @@ -1,5 +1,5 @@ import csharp from TypeParameter tp -where tp.getConstraints().hasUnmanagedTypeConstraint() +where tp.getConstraints().hasUnmanagedTypeConstraint() and tp.fromSource() select tp, "This type parameter is unmanaged." diff --git a/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected b/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected index 7f8a89af2e2..db98e8b9d0b 100644 --- a/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected +++ b/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected @@ -227,6 +227,10 @@ | file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | | file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | | file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | | file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | | file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | | file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | @@ -313,3 +317,5 @@ | file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | | file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | | file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | +| file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | +| file://:0:0:0:0 | [summary] call to valueSelector in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index faaef439eb5..81782ee2d7c 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -255,6 +255,7 @@ | System.Collections.Concurrent.ConcurrentStack<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Concurrent.ConcurrentStack<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Concurrent.ConcurrentStack<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.ConcurrentStack<>.GetEnumerator(Node) | element of argument -1 -> property Current of return (normal) | true | | System.Collections.Concurrent.IProducerConsumerCollection<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Concurrent.OrderablePartitioner<>.EnumerableDropIndices.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Collections.Concurrent.Partitioner.d__7.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | @@ -405,6 +406,7 @@ | System.Collections.Generic.SortedList<,>.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | | System.Collections.Generic.SortedList<,>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Generic.SortedList<,>.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.GetByIndex(int) | property Value of element of argument -1 -> return (normal) | true | | System.Collections.Generic.SortedList<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Collections.Generic.SortedList<,>.KeyList.Add(TKey) | argument 0 -> element of argument -1 | true | | System.Collections.Generic.SortedList<,>.KeyList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | @@ -467,6 +469,8 @@ | System.Collections.Hashtable.SyncHashtable.Clone() | element of argument 0 -> element of return (normal) | true | | System.Collections.Hashtable.SyncHashtable.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Hashtable.SyncHashtable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.SyncHashtable(Hashtable) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.SyncHashtable(Hashtable) | property Value of element of argument 0 -> property Value of element of return (normal) | true | | System.Collections.Hashtable.SyncHashtable.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | | System.Collections.Hashtable.SyncHashtable.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | | System.Collections.Hashtable.SyncHashtable.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | @@ -585,6 +589,8 @@ | System.Collections.SortedList.SyncSortedList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.SortedList.SyncSortedList.GetByIndex(int) | property Value of element of argument -1 -> return (normal) | true | | System.Collections.SortedList.SyncSortedList.GetValueList() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.SortedList.SyncSortedList.SyncSortedList(SortedList) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.SortedList.SyncSortedList.SyncSortedList(SortedList) | property Value of element of argument 0 -> property Value of element of return (normal) | true | | System.Collections.SortedList.SyncSortedList.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | | System.Collections.SortedList.SyncSortedList.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | | System.Collections.SortedList.SyncSortedList.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | @@ -633,6 +639,8 @@ | System.Collections.Specialized.OrderedDictionary.AsReadOnly() | element of argument 0 -> element of return (normal) | true | | System.Collections.Specialized.OrderedDictionary.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Specialized.OrderedDictionary.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.OrderedDictionary(OrderedDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.OrderedDictionary(OrderedDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | | System.Collections.Specialized.OrderedDictionary.OrderedDictionaryKeyValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | | System.Collections.Specialized.OrderedDictionary.OrderedDictionaryKeyValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Collections.Specialized.OrderedDictionary.get_Item(int) | property Value of element of argument -1 -> return (normal) | true | @@ -725,6 +733,10 @@ | System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[]) | property Value of element of argument 0 -> property Value of element of return (normal) | true | | System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | property Key of element of argument 0 -> property Key of element of return (normal) | true | | System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], int, String[], IComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], int, String[], IComparer) | property Key of element of argument 2 -> property Key of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], int, String[], IComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], int, String[], IComparer) | property Value of element of argument 2 -> property Value of element of return (normal) | true | | System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | element of argument -1 -> return (normal) | true | | System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | property Value of element of argument -1 -> return (normal) | true | | System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | element of argument -1 -> return (normal) | true | @@ -747,12 +759,28 @@ | System.Convert.ChangeType(object, Type, IFormatProvider) | argument 0 -> return (normal) | false | | System.Convert.ChangeType(object, TypeCode) | argument 0 -> return (normal) | false | | System.Convert.ChangeType(object, TypeCode, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ConvertToBase64Array(char*, byte*, int, int, bool) | argument 0 -> return (normal) | false | +| System.Convert.CopyToTempBufferWithoutWhiteSpace(ReadOnlySpan, Span, out int, out int) | argument 0 -> return (normal) | false | +| System.Convert.Decode(ref char, ref sbyte) | argument 0 -> return (normal) | false | +| System.Convert.DefaultToType(IConvertible, Type, IFormatProvider) | argument 0 -> return (normal) | false | | System.Convert.FromBase64CharArray(Char[], int, int) | argument 0 -> return (normal) | false | +| System.Convert.FromBase64CharPtr(char*, int) | argument 0 -> return (normal) | false | | System.Convert.FromBase64String(string) | argument 0 -> return (normal) | false | +| System.Convert.FromBase64_ComputeResultLength(char*, int) | argument 0 -> return (normal) | false | | System.Convert.FromHexString(ReadOnlySpan) | argument 0 -> return (normal) | false | | System.Convert.FromHexString(string) | argument 0 -> return (normal) | false | | System.Convert.GetTypeCode(object) | argument 0 -> return (normal) | false | | System.Convert.IsDBNull(object) | argument 0 -> return (normal) | false | +| System.Convert.IsSpace(char) | argument 0 -> return (normal) | false | +| System.Convert.ThrowByteOverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowCharOverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowInt16OverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowInt32OverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowInt64OverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowSByteOverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowUInt16OverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowUInt32OverflowException() | argument 0 -> return (normal) | false | +| System.Convert.ThrowUInt64OverflowException() | argument 0 -> return (normal) | false | | System.Convert.ToBase64CharArray(Byte[], int, int, Char[], int) | argument 0 -> return (normal) | false | | System.Convert.ToBase64CharArray(Byte[], int, int, Char[], int, Base64FormattingOptions) | argument 0 -> return (normal) | false | | System.Convert.ToBase64String(Byte[]) | argument 0 -> return (normal) | false | @@ -760,6 +788,7 @@ | System.Convert.ToBase64String(Byte[], int, int) | argument 0 -> return (normal) | false | | System.Convert.ToBase64String(Byte[], int, int, Base64FormattingOptions) | argument 0 -> return (normal) | false | | System.Convert.ToBase64String(ReadOnlySpan, Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64_CalculateAndValidateOutputLength(int, bool) | argument 0 -> return (normal) | false | | System.Convert.ToBoolean(DateTime) | argument 0 -> return (normal) | false | | System.Convert.ToBoolean(bool) | argument 0 -> return (normal) | false | | System.Convert.ToBoolean(byte) | argument 0 -> return (normal) | false | @@ -1059,9 +1088,11 @@ | System.Convert.ToUInt64(uint) | argument 0 -> return (normal) | false | | System.Convert.ToUInt64(ulong) | argument 0 -> return (normal) | false | | System.Convert.ToUInt64(ushort) | argument 0 -> return (normal) | false | +| System.Convert.TryDecodeFromUtf16(ReadOnlySpan, Span, out int, out int) | argument 0 -> return (normal) | false | | System.Convert.TryFromBase64Chars(ReadOnlySpan, Span, out int) | argument 0 -> return (normal) | false | | System.Convert.TryFromBase64String(string, Span, out int) | argument 0 -> return (normal) | false | | System.Convert.TryToBase64Chars(ReadOnlySpan, Span, out int, Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Convert.WriteThreeLowOrderBytes(ref byte, int) | argument 0 -> return (normal) | false | | System.Diagnostics.Tracing.CounterPayload.d__51.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Diagnostics.Tracing.CounterPayload.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | @@ -1070,6 +1101,10 @@ | System.Diagnostics.Tracing.EventPayload.Add(string, object) | argument 0 -> property Key of element of argument -1 | true | | System.Diagnostics.Tracing.EventPayload.Add(string, object) | argument 1 -> property Value of element of argument -1 | true | | System.Diagnostics.Tracing.EventPayload.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Diagnostics.Tracing.EventPayload.EventPayload(List, List) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.EventPayload(List, List) | property Key of element of argument 1 -> property Key of element of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.EventPayload(List, List) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.EventPayload(List, List) | property Value of element of argument 1 -> property Value of element of return (normal) | true | | System.Diagnostics.Tracing.EventPayload.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Diagnostics.Tracing.EventPayload.get_Item(string) | property Value of element of argument -1 -> return (normal) | true | | System.Diagnostics.Tracing.EventPayload.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | @@ -1126,8 +1161,11 @@ | System.IO.Compression.DeflateStream.CopyToStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | | System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel) | argument 0 -> return (normal) | false | | System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel, bool) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel, bool, int) | argument 0 -> return (normal) | false | | System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode) | argument 0 -> return (normal) | false | | System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode, bool) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode, bool, int, long) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode, long) | argument 0 -> return (normal) | false | | System.IO.Compression.DeflateStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | | System.IO.Compression.DeflateStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | | System.IO.Compression.DeflateStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | @@ -1181,6 +1219,7 @@ | System.IO.Path.Combine(string, string, string, string) | argument 3 -> return (normal) | false | | System.IO.Path.GetDirectoryName(ReadOnlySpan) | argument 0 -> return (normal) | false | | System.IO.Path.GetDirectoryName(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetDirectoryNameOffset(ReadOnlySpan) | argument 0 -> return (normal) | false | | System.IO.Path.GetExtension(ReadOnlySpan) | argument 0 -> return (normal) | false | | System.IO.Path.GetExtension(string) | argument 0 -> return (normal) | false | | System.IO.Path.GetFileName(ReadOnlySpan) | argument 0 -> return (normal) | false | @@ -1192,20 +1231,28 @@ | System.IO.Path.GetPathRoot(ReadOnlySpan) | argument 0 -> return (normal) | false | | System.IO.Path.GetPathRoot(string) | argument 0 -> return (normal) | false | | System.IO.Path.GetRelativePath(string, string) | argument 1 -> return (normal) | false | +| System.IO.Path.GetRelativePath(string, string, StringComparison) | argument 1 -> return (normal) | false | | System.IO.Pipes.PipeStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | | System.IO.Pipes.PipeStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | | System.IO.Pipes.PipeStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | | System.IO.Pipes.PipeStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | | System.IO.Pipes.PipeStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | | System.IO.Pipes.PipeStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Stream.BeginEndReadAsync(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.BeginEndWriteAsync(Byte[], int, int) | argument 0 -> argument -1 | false | | System.IO.Stream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.BeginReadInternal(Byte[], int, int, AsyncCallback, object, bool, bool) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Stream.BeginWriteInternal(Byte[], int, int, AsyncCallback, object, bool, bool) | argument 0 -> argument -1 | false | +| System.IO.Stream.BlockingBeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.BlockingBeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | | System.IO.Stream.CopyTo(Stream) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.CopyToAsync(Stream) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.CopyToAsync(Stream, CancellationToken) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.CopyToAsync(Stream, int) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.CopyToAsyncInternal(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.NullStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | | System.IO.Stream.NullStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | | System.IO.Stream.NullStream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | @@ -1247,6 +1294,7 @@ | System.IO.TextReader.ReadBlock(Span) | argument -1 -> return (normal) | false | | System.IO.TextReader.ReadBlockAsync(Char[], int, int) | argument -1 -> return (normal) | false | | System.IO.TextReader.ReadBlockAsync(Memory, CancellationToken) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadBlockAsyncInternal(Memory, CancellationToken) | argument -1 -> return (normal) | false | | System.IO.TextReader.ReadLine() | argument -1 -> return (normal) | false | | System.IO.TextReader.ReadLineAsync() | argument -1 -> return (normal) | false | | System.IO.TextReader.ReadToEnd() | argument -1 -> return (normal) | false | @@ -1271,6 +1319,7 @@ | System.Int32.TryParse(string, out int) | argument 0 -> return (out parameter 1) | false | | System.Lazy<>.Lazy(Func) | return (normal) of argument 0 -> property Value of return (normal) | true | | System.Lazy<>.Lazy(Func, LazyThreadSafetyMode) | return (normal) of argument 0 -> property Value of return (normal) | true | +| System.Lazy<>.Lazy(Func, LazyThreadSafetyMode, bool) | return (normal) of argument 0 -> property Value of return (normal) | true | | System.Lazy<>.Lazy(Func, bool) | return (normal) of argument 0 -> property Value of return (normal) | true | | System.Lazy<>.get_Value() | argument -1 -> return (normal) | false | | System.Linq.EmptyPartition<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | @@ -1529,13 +1578,16 @@ | System.Linq.Lookup<,>.d__19<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Lookup<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.OrderedEnumerable<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.OrderedEnumerable<>.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | | System.Linq.OrderedPartition<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.CancellableEnumerable.d__0<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.EnumerableWrapperWeakToStrong.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.ExceptionAggregator.d__0<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.ExceptionAggregator.d__1<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.GroupByGrouping<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.ListChunk<>.Add(TInputOutput) | argument 0 -> element of argument -1 | true | | System.Linq.Parallel.ListChunk<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.Lookup<,>.Add(IGrouping) | argument 0 -> element of argument -1 | true | | System.Linq.Parallel.Lookup<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.MergeExecutor<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | | System.Linq.Parallel.OrderedGroupByGrouping<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | @@ -1556,8 +1608,12 @@ | System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | argument 1 -> parameter 0 of argument 2 | true | | System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | element of argument 0 -> parameter 1 of argument 2 | true | | System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | return (normal) of argument 2 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, QueryAggregationOptions) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, QueryAggregationOptions) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, QueryAggregationOptions) | return (normal) of argument 3 -> return (normal) | true | | System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func) | element of argument 0 -> parameter 1 of argument 1 | true | | System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func) | return (normal) of argument 1 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func, QueryAggregationOptions) | return (normal) of argument 2 -> return (normal) | true | | System.Linq.ParallelEnumerable.All(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | | System.Linq.ParallelEnumerable.Any(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | | System.Linq.ParallelEnumerable.AsEnumerable(ParallelQuery) | element of argument 0 -> element of return (normal) | true | @@ -2000,6 +2056,7 @@ | System.Net.Security.SslStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | | System.Net.Security.SslStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | | System.Net.Security.SslStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.Net.WebUtility.HtmlEncode(ReadOnlySpan, ref ValueStringBuilder) | argument 0 -> return (normal) | false | | System.Net.WebUtility.HtmlEncode(string) | argument 0 -> return (normal) | false | | System.Net.WebUtility.HtmlEncode(string, TextWriter) | argument 0 -> return (normal) | false | | System.Net.WebUtility.UrlEncode(string) | argument 0 -> return (normal) | false | @@ -2305,6 +2362,7 @@ | System.Threading.Tasks.Task.ContinueWith(Action, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task.ContinueWith(Action, object, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task.ContinueWith(Action, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Action, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task.ContinueWith(Func, object) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task.ContinueWith(Func, object) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken) | argument 1 -> parameter 1 of argument 0 | true | @@ -2315,11 +2373,14 @@ | System.Threading.Tasks.Task.ContinueWith(Func, object, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.ContinueWith(Func, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, TaskScheduler, CancellationToken, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.FromResult(TResult) | argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.Run(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task.Run(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | @@ -2346,11 +2407,14 @@ | System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action>) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action>, CancellationToken) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action>, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | return (normal) of argument 0 -> property Result of return (normal) | true | @@ -2366,6 +2430,9 @@ | System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler, CancellationToken, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken) | argument -1 -> parameter 0 of argument 0 | true | @@ -2376,6 +2443,8 @@ | System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler, CancellationToken, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler, CancellationToken, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.GetAwaiter() | argument -1 -> field m_task of return (normal) | true | | System.Threading.Tasks.Task<>.Task(Func, object) | argument 1 -> parameter 0 of argument 0 | true | | System.Threading.Tasks.Task<>.Task(Func, object) | return (normal) of argument 0 -> property Result of return (normal) | true | @@ -2388,6 +2457,7 @@ | System.Threading.Tasks.Task<>.Task(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.Task(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.Task(Func, CancellationToken, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, Task, CancellationToken, TaskCreationOptions, InternalTaskOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.Task(Func, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | | System.Threading.Tasks.Task<>.get_Result() | argument -1 -> return (normal) | false | | System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | argument 0 -> parameter 0 of argument 1 | true | diff --git a/csharp/ql/test/library-tests/methods/Methods1.ql b/csharp/ql/test/library-tests/methods/Methods1.ql index fb8c2d4cdf9..09560396bd2 100644 --- a/csharp/ql/test/library-tests/methods/Methods1.ql +++ b/csharp/ql/test/library-tests/methods/Methods1.ql @@ -7,5 +7,6 @@ import csharp from Method s where s.hasName("Swap") and - s.isStatic() + s.isStatic() and + s.fromSource() select s diff --git a/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected b/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected index d4a68c97906..8159a38c348 100644 --- a/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected +++ b/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected @@ -1 +1 @@ -| // This file contains auto-generated code.\n// original-extractor-options: /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Net.dll /r:System.Web.dll /r:System.Net.HttpListener.dll /r:System.Collections.Specialized.dll /r:System.Private.Uri.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Parallel.dll /r:System.Collections.Concurrent.dll /r:System.Linq.Expressions.dll /r:System.Collections.dll /r:System.Linq.Queryable.dll /r:System.Linq.dll /r:System.Collections.NonGeneric.dll /r:System.ObjectModel.dll /r:System.ComponentModel.TypeConverter.dll /r:System.IO.Compression.dll /r:System.IO.Pipes.dll /r:System.Net.Primitives.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Primitives.dll /r:System.Text.RegularExpressions.dll ${testdir}/../../resources/stubs/System.Web.cs /r:System.Runtime.Serialization.Primitives.dll\n\nnamespace System\n{\n// Generated from `System.Uri` in `System.Private.Uri, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n}\n\nnamespace Collections\n{\n// Generated from `System.Collections.Queue` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Queue : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.SortedList` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedList : System.ICloneable, System.Collections.IEnumerable, System.Collections.IDictionary, System.Collections.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object GetByIndex(int index) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual void Remove(object key) => throw null;\n}\n\n// Generated from `System.Collections.Stack` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\nnamespace Concurrent\n{\n// Generated from `System.Collections.Concurrent.BlockingCollection<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class BlockingCollection : System.IDisposable, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public int Count { get => throw null; }\n public void Dispose() => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Concurrent.BlockingCollectionDebugView<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockingCollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Concurrent.IDictionaryDebugView<,>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass IDictionaryDebugView\n{\n}\n\n}\nnamespace Generic\n{\n// Generated from `System.Collections.Generic.CollectionDebugView<>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.DictionaryDebugView<,>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass DictionaryDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.QueueDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass QueueDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.SortedSet<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedSet : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public bool Add(T item) => throw null;\n public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Overlaps(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Remove(T item) => throw null;\n public bool SetEquals(System.Collections.Generic.IEnumerable other) => throw null;\n public int Count { get => throw null; }\n public virtual bool Contains(T item) => throw null;\n public virtual void Clear() => throw null;\n public virtual void IntersectWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void ExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void SymmetricExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void UnionWith(System.Collections.Generic.IEnumerable other) => throw null;\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n// Generated from `System.Collections.Generic.Stack<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public T Peek() => throw null;\n public int Count { get => throw null; }\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n}\n\n// Generated from `System.Collections.Generic.StackDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StackDebugView\n{\n}\n\n}\nnamespace Specialized\n{\n// Generated from `System.Collections.Specialized.NameObjectCollectionBase` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class NameObjectCollectionBase : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection\n{\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual int Count { get => throw null; }\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n public virtual void OnDeserialization(object sender) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Specialized.NameValueCollection` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\nnamespace ComponentModel\n{\n// Generated from `System.ComponentModel.ComponentConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\n// Generated from `System.ComponentModel.DefaultEventAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.DefaultPropertyAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.INotifyPropertyChanged` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface INotifyPropertyChanged\n{\n}\n\n// Generated from `System.ComponentModel.ReferenceConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeConverterAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverterAttribute : System.Attribute\n{\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProviderAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProvider` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class TypeDescriptionProvider\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptor` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptor\n{\n}\n\nnamespace Design\n{\n// Generated from `System.ComponentModel.Design.DesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class DesignerOptionService : System.ComponentModel.Design.IDesignerOptionService\n{\n}\n\n// Generated from `System.ComponentModel.Design.IDesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDesignerOptionService\n{\n}\n\n}\n}\nnamespace Dynamic\n{\n// Generated from `System.Dynamic.DynamicMetaObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DynamicMetaObject\n{\n}\n\n// Generated from `System.Dynamic.ExpandoObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ExpandoObject : System.Dynamic.IDynamicMetaObjectProvider, System.ComponentModel.INotifyPropertyChanged, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IDictionary, System.Collections.Generic.ICollection>\n{\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get => throw null; }\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get => throw null; }\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.ICollection>.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.IDictionary.ContainsKey(string key) => throw null;\n bool System.Collections.Generic.IDictionary.Remove(string key) => throw null;\n bool System.Collections.Generic.IDictionary.TryGetValue(string key, out object value) => throw null;\n int System.Collections.Generic.ICollection>.Count { get => throw null; }\n object this[string key] { get => throw null; set => throw null; }\n void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) => throw null;\n void System.Collections.Generic.ICollection>.Clear() => throw null;\n void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IDictionary.Add(string key, object value) => throw null;\n}\n\n// Generated from `System.Dynamic.IDynamicMetaObjectProvider` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDynamicMetaObjectProvider\n{\n}\n\nnamespace Utils\n{\n// Generated from `System.Dynamic.Utils.ListProvider<>` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class ListProvider : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection where T: class\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public bool Contains(T item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(T item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(T item) => throw null;\n public void Add(T item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void Insert(int index, T item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n}\n}\nnamespace IO\n{\nnamespace Compression\n{\n// Generated from `System.IO.Compression.DeflateStream` in `System.IO.Compression, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`\npublic class DeflateStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] array, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] array, int offset, int count) => throw null;\n public override int Read(System.Span buffer) => throw null;\n public override int ReadByte() => throw null;\n public override void CopyTo(System.IO.Stream destination, int bufferSize) => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] array, int offset, int count) => throw null;\n public override void Write(System.ReadOnlySpan buffer) => throw null;\n}\n\n}\n}\nnamespace Linq\n{\n// Generated from `System.Linq.Enumerable` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n// Generated from `System.Linq.Grouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Grouping : System.Linq.IGrouping, System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n TElement this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(TElement item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(TElement item) => throw null;\n int System.Collections.Generic.ICollection.Count { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(TElement item) => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n void System.Collections.Generic.ICollection.Add(TElement item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(TElement[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, TElement item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.IGrouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IGrouping : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IIListProvider<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IIListProvider : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.ILookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface ILookup : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n}\n\n// Generated from `System.Linq.IOrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IOrderedEnumerable : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IPartition<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IPartition : System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IQueryable` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n// Generated from `System.Linq.Lookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Lookup : System.Linq.ILookup, System.Linq.IIListProvider>, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.OrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class OrderedEnumerable : System.Linq.IPartition, System.Linq.IOrderedEnumerable, System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelEnumerable` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Linq.ParallelQuery, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n public virtual System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Queryable` in `System.Linq.Queryable, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.SystemLinq_GroupingDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_GroupingDebugView\n{\n}\n\n// Generated from `System.Linq.SystemLinq_LookupDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_LookupDebugView\n{\n}\n\nnamespace Expressions\n{\n// Generated from `System.Linq.Expressions.BlockExpressionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockExpressionList : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.Expression this[int index] { get => throw null; set => throw null; }\n public bool Contains(System.Linq.Expressions.Expression item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(System.Linq.Expressions.Expression item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(System.Linq.Expressions.Expression item) => throw null;\n public void Add(System.Linq.Expressions.Expression item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Linq.Expressions.Expression[] array, int index) => throw null;\n public void Insert(int index, System.Linq.Expressions.Expression item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Expression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class Expression\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.ParameterExpression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParameterExpression : System.Linq.Expressions.Expression\n{\n}\n\nnamespace Compiler\n{\n// Generated from `System.Linq.Expressions.Compiler.ParameterList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ParameterList : System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.ParameterExpression this[int index] { get => throw null; }\n public int Count { get => throw null; }\n}\n\n}\nnamespace Interpreter\n{\n// Generated from `System.Linq.Expressions.Interpreter.InstructionArray` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InstructionArray\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InstructionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InstructionList\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrameInfo` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InterpretedFrameInfo\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrame` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InterpretedFrame\n{\n}\n\n}\n}\nnamespace Parallel\n{\n// Generated from `System.Linq.Parallel.ListChunk<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ListChunk : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.Lookup<,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass Lookup : System.Linq.ILookup, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.PartitionerQueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass PartitionerQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n// Generated from `System.Linq.Parallel.QueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryOperator : System.Linq.ParallelQuery\n{\n public override System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.QueryResults<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryResults : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.Contains(T item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(T item) => throw null;\n int System.Collections.Generic.IList.IndexOf(T item) => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public int Count { get => throw null; }\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(T[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, T item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Parallel.ZipQueryOperator<,,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ZipQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n}\n}\nnamespace Net\n{\n// Generated from `System.Net.CookieCollection` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CookieCollection : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public bool Contains(System.Net.Cookie cookie) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool Remove(System.Net.Cookie cookie) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void Add(System.Net.Cookie cookie) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Array array, int index) => throw null;\n public void CopyTo(System.Net.Cookie[] array, int index) => throw null;\n}\n\n// Generated from `System.Net.Cookie` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Cookie\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Net.StreamFramer` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StreamFramer\n{\n}\n\nnamespace Security\n{\n// Generated from `System.Net.Security.AuthenticatedStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class AuthenticatedStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n}\n\n// Generated from `System.Net.Security.CipherSuitesPolicy` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CipherSuitesPolicy\n{\n}\n\n// Generated from `System.Net.Security.NegotiateStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NegotiateStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.SslStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SslStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadByte() => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.TlsCipherSuite` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic enum TlsCipherSuite\n{\n}\n\n// Generated from `System.Net.Security.TlsFrameHelper` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass TlsFrameHelper\n{\n}\n\n}\n}\nnamespace Runtime\n{\nnamespace Serialization\n{\n// Generated from `System.Runtime.Serialization.DataContractAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\n// Generated from `System.Runtime.Serialization.DataMemberAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\nnamespace Text\n{\nnamespace RegularExpressions\n{\n// Generated from `System.Text.RegularExpressions.Capture` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Capture\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.CollectionDebuggerProxy<>` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebuggerProxy\n{\n}\n\n// Generated from `System.Text.RegularExpressions.GroupCollection` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class GroupCollection : System.Collections.IList, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Text.RegularExpressions.Group this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.Generic.ICollection.Remove(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.IList.Contains(object value) => throw null;\n bool System.Collections.IList.IsFixedSize { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(System.Text.RegularExpressions.Group item) => throw null;\n int System.Collections.IList.Add(object value) => throw null;\n int System.Collections.IList.IndexOf(object value) => throw null;\n object this[int index] { get => throw null; set => throw null; }\n public System.Collections.Generic.IEnumerable Values { get => throw null; }\n public System.Collections.Generic.IEnumerable Keys { get => throw null; }\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public System.Text.RegularExpressions.Group this[string groupname] { get => throw null; }\n public bool ContainsKey(string key) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool TryGetValue(string key, out System.Text.RegularExpressions.Group value) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void CopyTo(System.Array array, int arrayIndex) => throw null;\n public void CopyTo(System.Text.RegularExpressions.Group[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.ICollection.Add(System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n void System.Collections.IList.Clear() => throw null;\n void System.Collections.IList.Insert(int index, object value) => throw null;\n void System.Collections.IList.Remove(object value) => throw null;\n void System.Collections.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.Group` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Group : System.Text.RegularExpressions.Capture\n{\n}\n\n// Generated from `System.Text.RegularExpressions.Match` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Match : System.Text.RegularExpressions.Group\n{\n}\n\n// Generated from `System.Text.RegularExpressions.RegexOptions` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\n[System.Flags]\npublic enum RegexOptions\n{\n IgnoreCase,\n}\n\n// Generated from `System.Text.RegularExpressions.Regex` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public override string ToString() => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n}\n}\nnamespace Timers\n{\n// Generated from `System.Timers.TimersDescriptionAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\n// Generated from `System.Windows.Markup.ValueSerializerAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n | +| // This file contains auto-generated code.\n// original-extractor-options: /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Net.dll /r:System.Web.dll /r:System.Net.HttpListener.dll /r:System.Collections.Specialized.dll /r:System.Private.Uri.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Parallel.dll /r:System.Collections.Concurrent.dll /r:System.Linq.Expressions.dll /r:System.Collections.dll /r:System.Linq.Queryable.dll /r:System.Linq.dll /r:System.Collections.NonGeneric.dll /r:System.ObjectModel.dll /r:System.ComponentModel.TypeConverter.dll /r:System.IO.Compression.dll /r:System.IO.Pipes.dll /r:System.Net.Primitives.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Primitives.dll /r:System.Text.RegularExpressions.dll ${testdir}/../../resources/stubs/System.Web.cs /r:System.Runtime.Serialization.Primitives.dll\n\nnamespace System\n{\n// Generated from `System.Uri` in `System.Private.Uri, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n}\n\nnamespace Collections\n{\n// Generated from `System.Collections.Queue` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Queue : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.SortedList` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedList : System.ICloneable, System.Collections.IEnumerable, System.Collections.IDictionary, System.Collections.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object GetByIndex(int index) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual void Remove(object key) => throw null;\n}\n\n// Generated from `System.Collections.Stack` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\nnamespace Concurrent\n{\n// Generated from `System.Collections.Concurrent.BlockingCollection<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class BlockingCollection : System.IDisposable, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public int Count { get => throw null; }\n public void Dispose() => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Concurrent.BlockingCollectionDebugView<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockingCollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Concurrent.ConcurrentStack<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ConcurrentStack : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Concurrent.IProducerConsumerCollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Concurrent.IProducerConsumerCollection.TryAdd(T item) => throw null;\n bool System.Collections.Concurrent.IProducerConsumerCollection.TryTake(out T item) => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public T[] ToArray() => throw null;\n public int Count { get => throw null; }\n public void CopyTo(T[] array, int index) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Concurrent.IDictionaryDebugView<,>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass IDictionaryDebugView\n{\n}\n\n// Generated from `System.Collections.Concurrent.Partitioner` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Partitioner\n{\n}\n\n}\nnamespace Generic\n{\n// Generated from `System.Collections.Generic.CollectionDebugView<>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.DictionaryDebugView<,>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass DictionaryDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.QueueDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass QueueDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.SortedSet<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedSet : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public bool Add(T item) => throw null;\n public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Overlaps(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Remove(T item) => throw null;\n public bool SetEquals(System.Collections.Generic.IEnumerable other) => throw null;\n public int Count { get => throw null; }\n public virtual bool Contains(T item) => throw null;\n public virtual void Clear() => throw null;\n public virtual void IntersectWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void ExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void SymmetricExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void UnionWith(System.Collections.Generic.IEnumerable other) => throw null;\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n// Generated from `System.Collections.Generic.Stack<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public T Peek() => throw null;\n public int Count { get => throw null; }\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n}\n\n// Generated from `System.Collections.Generic.StackDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StackDebugView\n{\n}\n\n}\nnamespace Specialized\n{\n// Generated from `System.Collections.Specialized.NameObjectCollectionBase` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class NameObjectCollectionBase : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection\n{\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual int Count { get => throw null; }\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n public virtual void OnDeserialization(object sender) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Specialized.NameValueCollection` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\nnamespace ComponentModel\n{\n// Generated from `System.ComponentModel.ComponentConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\n// Generated from `System.ComponentModel.DefaultEventAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultEventAttribute : System.Attribute\n{\n private static DefaultEventAttribute() => throw null;\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.DefaultPropertyAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultPropertyAttribute : System.Attribute\n{\n private static DefaultPropertyAttribute() => throw null;\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.INotifyPropertyChanged` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface INotifyPropertyChanged\n{\n}\n\n// Generated from `System.ComponentModel.ReferenceConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeConverterAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverterAttribute : System.Attribute\n{\n private static TypeConverterAttribute() => throw null;\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProviderAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProvider` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class TypeDescriptionProvider\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptor` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptor\n{\n}\n\nnamespace Design\n{\n// Generated from `System.ComponentModel.Design.DesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class DesignerOptionService : System.ComponentModel.Design.IDesignerOptionService\n{\n}\n\n// Generated from `System.ComponentModel.Design.IDesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDesignerOptionService\n{\n}\n\n}\n}\nnamespace Dynamic\n{\n// Generated from `System.Dynamic.BindingRestrictions` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class BindingRestrictions\n{\n}\n\n// Generated from `System.Dynamic.DynamicMetaObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DynamicMetaObject\n{\n}\n\n// Generated from `System.Dynamic.ExpandoObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ExpandoObject : System.Dynamic.IDynamicMetaObjectProvider, System.ComponentModel.INotifyPropertyChanged, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IDictionary, System.Collections.Generic.ICollection>\n{\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get => throw null; }\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get => throw null; }\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.ICollection>.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.IDictionary.ContainsKey(string key) => throw null;\n bool System.Collections.Generic.IDictionary.Remove(string key) => throw null;\n bool System.Collections.Generic.IDictionary.TryGetValue(string key, out object value) => throw null;\n int System.Collections.Generic.ICollection>.Count { get => throw null; }\n object this[string key] { get => throw null; set => throw null; }\n void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) => throw null;\n void System.Collections.Generic.ICollection>.Clear() => throw null;\n void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IDictionary.Add(string key, object value) => throw null;\n}\n\n// Generated from `System.Dynamic.IDynamicMetaObjectProvider` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDynamicMetaObjectProvider\n{\n}\n\n// Generated from `System.Dynamic.UpdateDelegates` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic class UpdateDelegates\n{\n}\n\nnamespace Utils\n{\n// Generated from `System.Dynamic.Utils.ListProvider<>` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class ListProvider : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection where T: class\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public bool Contains(T item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(T item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(T item) => throw null;\n public void Add(T item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void Insert(int index, T item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n}\n}\nnamespace IO\n{\nnamespace Compression\n{\n// Generated from `System.IO.Compression.DeflateManagedStream` in `System.IO.Compression, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`\nclass DeflateManagedStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] array, int offset, int count) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] array, int offset, int count) => throw null;\n}\n\n// Generated from `System.IO.Compression.DeflateStream` in `System.IO.Compression, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`\npublic class DeflateStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] array, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] array, int offset, int count) => throw null;\n public override int Read(System.Span buffer) => throw null;\n public override int ReadByte() => throw null;\n public override void CopyTo(System.IO.Stream destination, int bufferSize) => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] array, int offset, int count) => throw null;\n public override void Write(System.ReadOnlySpan buffer) => throw null;\n}\n\n}\nnamespace Pipes\n{\n// Generated from `System.IO.Pipes.NamedPipeServerStream` in `System.IO.Pipes, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NamedPipeServerStream : System.IO.Pipes.PipeStream\n{\n}\n\n// Generated from `System.IO.Pipes.PipeStream` in `System.IO.Pipes, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class PipeStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int Read(System.Span buffer) => throw null;\n public override int ReadByte() => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n public override void Write(System.ReadOnlySpan buffer) => throw null;\n public override void WriteByte(System.Byte value) => throw null;\n}\n\n}\n}\nnamespace Linq\n{\n// Generated from `System.Linq.Enumerable` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n// Generated from `System.Linq.Grouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Grouping : System.Linq.IGrouping, System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n TElement this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(TElement item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(TElement item) => throw null;\n int System.Collections.Generic.ICollection.Count { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(TElement item) => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n void System.Collections.Generic.ICollection.Add(TElement item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(TElement[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, TElement item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.IGrouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IGrouping : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IIListProvider<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IIListProvider : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.ILookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface ILookup : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n}\n\n// Generated from `System.Linq.IOrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IOrderedEnumerable : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IPartition<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IPartition : System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IQueryable` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n// Generated from `System.Linq.Lookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Lookup : System.Linq.ILookup, System.Linq.IIListProvider>, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.OrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class OrderedEnumerable : System.Linq.IPartition, System.Linq.IOrderedEnumerable, System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelEnumerable` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Linq.ParallelQuery, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n public virtual System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Queryable` in `System.Linq.Queryable, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.SystemLinq_GroupingDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_GroupingDebugView\n{\n}\n\n// Generated from `System.Linq.SystemLinq_LookupDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_LookupDebugView\n{\n}\n\nnamespace Expressions\n{\n// Generated from `System.Linq.Expressions.BlockExpressionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockExpressionList : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.Expression this[int index] { get => throw null; set => throw null; }\n public bool Contains(System.Linq.Expressions.Expression item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(System.Linq.Expressions.Expression item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(System.Linq.Expressions.Expression item) => throw null;\n public void Add(System.Linq.Expressions.Expression item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Linq.Expressions.Expression[] array, int index) => throw null;\n public void Insert(int index, System.Linq.Expressions.Expression item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Expression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class Expression\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.ParameterExpression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParameterExpression : System.Linq.Expressions.Expression\n{\n}\n\nnamespace Compiler\n{\n// Generated from `System.Linq.Expressions.Compiler.CompilerScope` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CompilerScope\n{\n}\n\n// Generated from `System.Linq.Expressions.Compiler.ParameterList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ParameterList : System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.ParameterExpression this[int index] { get => throw null; }\n public int Count { get => throw null; }\n}\n\n}\nnamespace Interpreter\n{\n// Generated from `System.Linq.Expressions.Interpreter.HybridReferenceDictionary<,>` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass HybridReferenceDictionary where TKey: class\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InstructionArray` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InstructionArray\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InstructionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InstructionList\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrameInfo` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InterpretedFrameInfo\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrame` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InterpretedFrame\n{\n}\n\n}\n}\nnamespace Parallel\n{\n// Generated from `System.Linq.Parallel.CancellableEnumerable` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic class CancellableEnumerable\n{\n}\n\n// Generated from `System.Linq.Parallel.ExceptionAggregator` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic class ExceptionAggregator\n{\n}\n\n// Generated from `System.Linq.Parallel.ListChunk<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ListChunk : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.Lookup<,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass Lookup : System.Linq.ILookup, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.PartitionerQueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass PartitionerQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n// Generated from `System.Linq.Parallel.QueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryOperator : System.Linq.ParallelQuery\n{\n public override System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.QueryResults<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryResults : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.Contains(T item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(T item) => throw null;\n int System.Collections.Generic.IList.IndexOf(T item) => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public int Count { get => throw null; }\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(T[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, T item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Parallel.ZipQueryOperator<,,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ZipQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n}\n}\nnamespace Net\n{\n// Generated from `System.Net.CookieCollection` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CookieCollection : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public bool Contains(System.Net.Cookie cookie) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool Remove(System.Net.Cookie cookie) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void Add(System.Net.Cookie cookie) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Array array, int index) => throw null;\n public void CopyTo(System.Net.Cookie[] array, int index) => throw null;\n}\n\n// Generated from `System.Net.Cookie` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Cookie\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Net.HttpResponseStream` in `System.Net.HttpListener, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51`\nclass HttpResponseStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int size, System.AsyncCallback callback, object state) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int size, System.AsyncCallback callback, object state) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int size) => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int size) => throw null;\n}\n\n// Generated from `System.Net.StreamFramer` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StreamFramer\n{\n}\n\nnamespace Security\n{\n// Generated from `System.Net.Security.AuthenticatedStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class AuthenticatedStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n}\n\n// Generated from `System.Net.Security.CipherSuitesPolicy` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CipherSuitesPolicy\n{\n}\n\n// Generated from `System.Net.Security.NegotiateStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NegotiateStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.SslStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SslStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadByte() => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.TlsCipherSuite` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic enum TlsCipherSuite\n{\n}\n\n// Generated from `System.Net.Security.TlsFrameHelper` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass TlsFrameHelper\n{\n}\n\n}\nnamespace WebSockets\n{\n// Generated from `System.Net.WebSockets.HttpWebSocket` in `System.Net.HttpListener, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51`\nstatic class HttpWebSocket\n{\n}\n\n}\n}\nnamespace Runtime\n{\nnamespace Serialization\n{\n// Generated from `System.Runtime.Serialization.DataContractAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\n// Generated from `System.Runtime.Serialization.DataMemberAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\nnamespace Security\n{\nnamespace Cryptography\n{\n// Generated from `System.Security.Cryptography.CryptoStream` in `System.Security.Cryptography.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CryptoStream : System.IO.Stream, System.IDisposable\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadByte() => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n public override void WriteByte(System.Byte value) => throw null;\n}\n\n// Generated from `System.Security.Cryptography.HashAlgorithm` in `System.Security.Cryptography.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class HashAlgorithm : System.Security.Cryptography.ICryptoTransform, System.IDisposable\n{\n public void Dispose() => throw null;\n}\n\n// Generated from `System.Security.Cryptography.ICryptoTransform` in `System.Security.Cryptography.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface ICryptoTransform : System.IDisposable\n{\n}\n\n}\n}\nnamespace Text\n{\nnamespace RegularExpressions\n{\n// Generated from `System.Text.RegularExpressions.Capture` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Capture\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.CollectionDebuggerProxy<>` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebuggerProxy\n{\n}\n\n// Generated from `System.Text.RegularExpressions.GroupCollection` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class GroupCollection : System.Collections.IList, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Text.RegularExpressions.Group this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.Generic.ICollection.Remove(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.IList.Contains(object value) => throw null;\n bool System.Collections.IList.IsFixedSize { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(System.Text.RegularExpressions.Group item) => throw null;\n int System.Collections.IList.Add(object value) => throw null;\n int System.Collections.IList.IndexOf(object value) => throw null;\n object this[int index] { get => throw null; set => throw null; }\n public System.Collections.Generic.IEnumerable Values { get => throw null; }\n public System.Collections.Generic.IEnumerable Keys { get => throw null; }\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public System.Text.RegularExpressions.Group this[string groupname] { get => throw null; }\n public bool ContainsKey(string key) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool TryGetValue(string key, out System.Text.RegularExpressions.Group value) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void CopyTo(System.Array array, int arrayIndex) => throw null;\n public void CopyTo(System.Text.RegularExpressions.Group[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.ICollection.Add(System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n void System.Collections.IList.Clear() => throw null;\n void System.Collections.IList.Insert(int index, object value) => throw null;\n void System.Collections.IList.Remove(object value) => throw null;\n void System.Collections.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.Group` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Group : System.Text.RegularExpressions.Capture\n{\n}\n\n// Generated from `System.Text.RegularExpressions.Match` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Match : System.Text.RegularExpressions.Group\n{\n}\n\n// Generated from `System.Text.RegularExpressions.RegexOptions` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\n[System.Flags]\npublic enum RegexOptions\n{\n IgnoreCase,\n}\n\n// Generated from `System.Text.RegularExpressions.Regex` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public override string ToString() => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n}\n}\nnamespace Timers\n{\n// Generated from `System.Timers.TimersDescriptionAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TimersDescriptionAttribute\n{\n internal TimersDescriptionAttribute(string description, string defaultValue) => throw null;\n public TimersDescriptionAttribute(string description) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\n// Generated from `System.Windows.Markup.ValueSerializerAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n | From 3b68c87b6ca85e308a648de716ac94517dc089de Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 3 Jun 2021 13:25:36 +0200 Subject: [PATCH 138/272] Python: Add sensitive data test-cases --- .../test/experimental/dataflow/sensitive-data/test.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/python/ql/test/experimental/dataflow/sensitive-data/test.py b/python/ql/test/experimental/dataflow/sensitive-data/test.py index 7db57fff2fa..75e0367e776 100644 --- a/python/ql/test/experimental/dataflow/sensitive-data/test.py +++ b/python/ql/test/experimental/dataflow/sensitive-data/test.py @@ -20,14 +20,24 @@ fetch_certificate() # $ SensitiveDataSource=certificate account_id() # $ SensitiveDataSource=id safe_to_store = encrypt_password(pwd) +f = get_password +f() # $ SensitiveDataSource=password + # attributes foo = ObjectFromDatabase() foo.secret # $ SensitiveDataSource=secret foo.username # $ SensitiveDataSource=id +# plain variables +password = some_function() +print(password) # $ MISSING: SensitiveDataSource=password + # Special handling of lookups of sensitive properties request.args["password"], # $ MISSING: SensitiveDataSource=password request.args.get("password") # $ SensitiveDataSource=password +x = "password" +request.args.get(x) # $ SensitiveDataSource=password + # I don't think handling `getlist` is super important, just included it to show what we don't handle request.args.getlist("password")[0] # $ MISSING: SensitiveDataSource=password From d0b6808299d1469e9c9a11f76dca36fcea4deb93 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Jun 2021 15:52:44 +0200 Subject: [PATCH 139/272] Java: Move common CSV logic for sources and sinks into shared library --- .../code/java/dataflow/ExternalFlow.qll | 194 +++--------------- .../dataflow/internal/DataFlowDispatch.qll | 10 +- .../java/dataflow/internal/DataFlowUtil.qll | 3 +- .../dataflow/internal/FlowSummaryImpl.qll | 121 ++++++++++- .../internal/FlowSummaryImplSpecific.qll | 103 +++++++++- .../code/java/dispatch/DispatchFlow.qll | 1 + .../src/semmle/code/java/dispatch/ObjFlow.qll | 1 + 7 files changed, 256 insertions(+), 177 deletions(-) diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 21aa7610de7..45d7dafb7f4 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -68,6 +68,7 @@ import java private import semmle.code.java.dataflow.DataFlow::DataFlow private import internal.DataFlowPrivate private import internal.FlowSummaryImpl::Private::External +private import internal.FlowSummaryImplSpecific private import FlowSummary /** @@ -359,7 +360,8 @@ private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } -private predicate sourceModel( +/** Holds if a source model exists for the given parameters. */ +predicate sourceModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, string output, string kind ) { @@ -377,7 +379,8 @@ private predicate sourceModel( ) } -private predicate sinkModel( +/** Holds if a sink model exists for the given parameters. */ +predicate sinkModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, string input, string kind ) { @@ -395,7 +398,8 @@ private predicate sinkModel( ) } -private predicate summaryModel( +/** Holds if a summary model exists for the given parameters. */ +predicate summaryModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, string input, string output, string kind ) { @@ -600,7 +604,8 @@ private Element interpretElement0( ) } -private Element interpretElement( +/** Gets the source/sink/summary element corresponding to the supplied parameters. */ +Element interpretElement( string namespace, string type, boolean subtypes, string name, string signature, string ext ) { elementSpec(namespace, type, subtypes, name, signature, ext) and @@ -611,166 +616,25 @@ private Element interpretElement( ) } -private predicate sourceElement(Element e, string output, string kind) { - exists( - string namespace, string type, boolean subtypes, string name, string signature, string ext - | - sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and - e = interpretElement(namespace, type, subtypes, name, signature, ext) - ) +cached +private module Cached { + /** + * Holds if `node` is specified as a source with the given kind in a CSV flow + * model. + */ + cached + predicate sourceNode(Node node, string kind) { + exists(InterpretNode n | isSourceNode(n, kind) and n.asNode() = node) + } + + /** + * Holds if `node` is specified as a sink with the given kind in a CSV flow + * model. + */ + cached + predicate sinkNode(Node node, string kind) { + exists(InterpretNode n | isSinkNode(n, kind) and n.asNode() = node) + } } -private predicate sinkElement(Element e, string input, string kind) { - exists( - string namespace, string type, boolean subtypes, string name, string signature, string ext - | - sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and - e = interpretElement(namespace, type, subtypes, name, signature, ext) - ) -} - -/** - * Holds if an external flow summary exists for `e` with input specification - * `input`, output specification `output`, and kind `kind`. - */ -predicate summaryElement(Element e, string input, string output, string kind) { - exists( - string namespace, string type, boolean subtypes, string name, string signature, string ext - | - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and - e = interpretElement(namespace, type, subtypes, name, signature, ext) - ) -} - -/** Gets a specification used in a source model, sink model, or summary model. */ -string inOutSpec() { - sourceModel(_, _, _, _, _, _, result, _) or - sinkModel(_, _, _, _, _, _, result, _) or - summaryModel(_, _, _, _, _, _, result, _, _) or - summaryModel(_, _, _, _, _, _, _, result, _) -} - -private predicate inputNeedsReference(string c) { - c = "Argument" or - parseArg(c, _) -} - -private predicate outputNeedsReference(string c) { - c = "Argument" or - parseArg(c, _) or - c = "ReturnValue" -} - -private predicate sourceElementRef(Top ref, string output, string kind) { - exists(Element e | - sourceElement(e, output, kind) and - if outputNeedsReference(specLast(output)) - then ref.(Call).getCallee().getSourceDeclaration() = e - else ref = e - ) -} - -private predicate sinkElementRef(Top ref, string input, string kind) { - exists(Element e | - sinkElement(e, input, kind) and - if inputNeedsReference(specLast(input)) - then ref.(Call).getCallee().getSourceDeclaration() = e - else ref = e - ) -} - -private predicate summaryElementRef(Top ref, string input, string output, string kind) { - exists(Element e | - summaryElement(e, input, output, kind) and - if inputNeedsReference(specLast(input)) - then ref.(Call).getCallee().getSourceDeclaration() = e - else ref = e - ) -} - -private newtype TAstOrNode = - TAst(Top t) or - TNode(Node n) - -private predicate interpretOutput(string output, int idx, Top ref, TAstOrNode node) { - ( - sourceElementRef(ref, output, _) or - summaryElementRef(ref, _, output, _) - ) and - specLength(output, idx) and - node = TAst(ref) - or - exists(Top mid, string c, Node n | - interpretOutput(output, idx + 1, ref, TAst(mid)) and - specSplit(output, c, idx) and - node = TNode(n) - | - exists(int pos | n.(PostUpdateNode).getPreUpdateNode().(ArgumentNode).argumentOf(mid, pos) | - c = "Argument" or parseArg(c, pos) - ) - or - exists(int pos | n.(ParameterNode).isParameterOf(mid, pos) | - c = "Parameter" or parseParam(c, pos) - ) - or - (c = "Parameter" or c = "") and - n.asParameter() = mid - or - c = "ReturnValue" and - n.asExpr().(Call) = mid - or - c = "" and - n.asExpr().(FieldRead).getField() = mid - ) -} - -private predicate interpretInput(string input, int idx, Top ref, TAstOrNode node) { - ( - sinkElementRef(ref, input, _) or - summaryElementRef(ref, input, _, _) - ) and - specLength(input, idx) and - node = TAst(ref) - or - exists(Top mid, string c, Node n | - interpretInput(input, idx + 1, ref, TAst(mid)) and - specSplit(input, c, idx) and - node = TNode(n) - | - exists(int pos | n.(ArgumentNode).argumentOf(mid, pos) | c = "Argument" or parseArg(c, pos)) - or - exists(ReturnStmt ret | - c = "ReturnValue" and - n.asExpr() = ret.getResult() and - mid = ret.getEnclosingCallable() - ) - or - exists(FieldWrite fw | - c = "" and - fw.getField() = mid and - n.asExpr() = fw.getRHS() - ) - ) -} - -/** - * Holds if `node` is specified as a source with the given kind in a CSV flow - * model. - */ -predicate sourceNode(Node node, string kind) { - exists(Top ref, string output | - sourceElementRef(ref, output, kind) and - interpretOutput(output, 0, ref, TNode(node)) - ) -} - -/** - * Holds if `node` is specified as a sink with the given kind in a CSV flow - * model. - */ -predicate sinkNode(Node node, string kind) { - exists(Top ref, string input | - sinkElementRef(ref, input, kind) and - interpretInput(input, 0, ref, TNode(node)) - ) -} +import Cached diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index 2b6179bfc96..8324959190a 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -4,13 +4,21 @@ private import DataFlowUtil private import semmle.code.java.dataflow.InstanceAccess private import semmle.code.java.dataflow.FlowSummary private import semmle.code.java.dispatch.VirtualDispatch as VirtualDispatch +private import semmle.code.java.dataflow.internal.FlowSummaryImplSpecific private module DispatchImpl { /** Gets a viable implementation of the target of the given `Call`. */ Callable viableCallable(Call c) { result = VirtualDispatch::viableCallable(c) or - result.(SummarizedCallable) = c.getCallee().getSourceDeclaration() + result = c.getCallee().getSourceDeclaration() and + ( + result instanceof SummarizedCallable + or + sourceElement(result, _, _) + or + sinkElement(result, _, _) + ) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll index e25ab24cfbb..c630af42acb 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -9,10 +9,11 @@ private import semmle.code.java.controlflow.Guards private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.dataflow.FlowSummary -import semmle.code.java.dataflow.InstanceAccess +private import semmle.code.java.dataflow.InstanceAccess private import FlowSummaryImpl as FlowSummaryImpl private import TaintTrackingUtil as TaintTrackingUtil import DataFlowNodes::Public +import semmle.code.Unit /** Holds if `n` is an access to an unqualified `this` at `cfgnode`. */ private predicate thisAccess(Node n, ControlFlowNode cfgnode) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index da6f89071ef..22b4b343524 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -9,6 +9,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public +private import DataFlowImplCommon as DataFlowImplCommon /** Provides classes and predicates for defining flow summaries. */ module Public { @@ -178,7 +179,6 @@ module Public { */ module Private { private import Public - private import DataFlowImplCommon as DataFlowImplCommon newtype TSummaryComponent = TContentSummaryComponent(Content c) or @@ -580,6 +580,14 @@ module Private { * summaries into a `SummarizedCallable`s. */ module External { + /** Holds if `spec` is a relevant external specification. */ + private predicate relevantSpec(string spec) { + summaryElement(_, spec, _, _) or + summaryElement(_, _, spec, _) or + sourceElement(_, spec, _) or + sinkElement(_, spec, _) + } + /** Holds if the `n`th component of specification `s` is `c`. */ predicate specSplit(string s, string c, int n) { relevantSpec(s) and s.splitAt(" of ", n) = c } @@ -629,6 +637,8 @@ module Private { or exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos)) or + c = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind()) + or result = interpretComponentSpecific(c) ) } @@ -664,13 +674,13 @@ module Private { } private class SummarizedCallableExternal extends SummarizedCallable { - SummarizedCallableExternal() { externalSummary(this, _, _, _) } + SummarizedCallableExternal() { summaryElement(this, _, _, _) } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { exists(string inSpec, string outSpec, string kind | - externalSummary(this, inSpec, outSpec, kind) and + summaryElement(this, inSpec, outSpec, kind) and interpretSpec(inSpec, 0, input) and interpretSpec(outSpec, 0, output) | @@ -686,6 +696,111 @@ module Private { specSplit(spec, c, _) and not exists(interpretComponent(c)) } + + private predicate inputNeedsReference(string c) { + c = "Argument" or + parseArg(c, _) + } + + private predicate outputNeedsReference(string c) { + c = "Argument" or + parseArg(c, _) or + c = "ReturnValue" + } + + private predicate sourceElementRef(InterpretNode ref, string output, string kind) { + exists(SourceOrSinkElement e | + sourceElement(e, output, kind) and + if outputNeedsReference(specLast(output)) + then viableCallable(ref.asCall()) = any(InterpretNode n | n.asElement() = e).asCallable() + else ref.asElement() = e + ) + } + + private predicate sinkElementRef(InterpretNode ref, string input, string kind) { + exists(SourceOrSinkElement e | + sinkElement(e, input, kind) and + if inputNeedsReference(specLast(input)) + then viableCallable(ref.asCall()) = any(InterpretNode n | n.asElement() = e).asCallable() + else ref.asElement() = e + ) + } + + private predicate interpretOutput(string output, int idx, InterpretNode ref, InterpretNode node) { + sourceElementRef(ref, output, _) and + specLength(output, idx) and + node = ref + or + exists(InterpretNode mid, string c | + interpretOutput(output, idx + 1, ref, mid) and + specSplit(output, c, idx) + | + exists(int pos | + node.asNode() + .(PostUpdateNode) + .getPreUpdateNode() + .(ArgumentNode) + .argumentOf(mid.asCall(), pos) + | + c = "Argument" or parseArg(c, pos) + ) + or + exists(int pos | node.asNode().(ParameterNode).isParameterOf(mid.asCallable(), pos) | + c = "Parameter" or parseParam(c, pos) + ) + or + c = "ReturnValue" and + node.asNode() = getAnOutNode(mid.asCall(), getReturnValueKind()) + or + interpretOutputSpecific(c, mid, node) + ) + } + + private predicate interpretInput(string input, int idx, InterpretNode ref, InterpretNode node) { + sinkElementRef(ref, input, _) and + specLength(input, idx) and + node = ref + or + exists(InterpretNode mid, string c | + interpretInput(input, idx + 1, ref, mid) and + specSplit(input, c, idx) + | + exists(int pos | node.asNode().(ArgumentNode).argumentOf(mid.asCall(), pos) | + c = "Argument" or parseArg(c, pos) + ) + or + exists(ReturnNode ret | + c = "ReturnValue" and + ret = node.asNode() and + ret.getKind() = getReturnValueKind() and + mid.asCallable() = DataFlowImplCommon::getNodeEnclosingCallable(ret) + ) + or + interpretInputSpecific(c, mid, node) + ) + } + + /** + * Holds if `node` is specified as a source with the given kind in a CSV flow + * model. + */ + predicate isSourceNode(InterpretNode node, string kind) { + exists(InterpretNode ref, string output | + sourceElementRef(ref, output, kind) and + interpretOutput(output, 0, ref, node) + ) + } + + /** + * Holds if `node` is specified as a sink with the given kind in a CSV flow + * model. + */ + predicate isSinkNode(InterpretNode node, string kind) { + exists(InterpretNode ref, string input | + sinkElementRef(ref, input, kind) and + interpretInput(input, 0, ref, node) + ) + } } /** Provides a query predicate for outputting a set of relevant flow summaries. */ diff --git a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index 327ddfb50dd..61e04946a4e 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -51,22 +51,22 @@ DataFlowType getCallbackParameterType(DataFlowType t, int i) { none() } */ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } -/** Holds if `spec` is a relevant external specification. */ -predicate relevantSpec(string spec) { spec = inOutSpec() } - /** * Holds if an external flow summary exists for `c` with input specification * `input`, output specification `output`, and kind `kind`. */ -predicate externalSummary(DataFlowCallable c, string input, string output, string kind) { - summaryElement(c, input, output, kind) +predicate summaryElement(DataFlowCallable c, string input, string output, string kind) { + exists( + string namespace, string type, boolean subtypes, string name, string signature, string ext + | + summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and + c = interpretElement(namespace, type, subtypes, name, signature, ext) + ) } /** Gets the summary component for specification component `c`, if any. */ bindingset[c] SummaryComponent interpretComponentSpecific(string c) { - c = "ReturnValue" and result = SummaryComponent::return(_) - or c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0)) or c = "Element" and result = SummaryComponent::content(any(CollectionContent c0)) @@ -75,3 +75,92 @@ SummaryComponent interpretComponentSpecific(string c) { or c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0)) } + +class SourceOrSinkElement = Top; + +/** + * Holds if an external source specification exists for `e` with output specification + * `output` and kind `kind`. + */ +predicate sourceElement(SourceOrSinkElement e, string output, string kind) { + exists( + string namespace, string type, boolean subtypes, string name, string signature, string ext + | + sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and + e = interpretElement(namespace, type, subtypes, name, signature, ext) + ) +} + +/** + * Holds if an external sink specification exists for `e` with input specification + * `input` and kind `kind`. + */ +predicate sinkElement(SourceOrSinkElement e, string input, string kind) { + exists( + string namespace, string type, boolean subtypes, string name, string signature, string ext + | + sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and + e = interpretElement(namespace, type, subtypes, name, signature, ext) + ) +} + +/** Gets the return kind corresponding to specification `"ReturnValue"`. */ +ReturnKind getReturnValueKind() { any() } + +private newtype TInterpretNode = + TElement(SourceOrSinkElement n) or + TNode(Node n) + +/** An entity used to interpret a source/sink specification. */ +class InterpretNode extends TInterpretNode { + /** Gets the element that this node corresponds to, if any. */ + SourceOrSinkElement asElement() { this = TElement(result) } + + /** Gets the data-flow node that this node corresponds to, if any. */ + Node asNode() { this = TNode(result) } + + /** Gets the call that this node corresponds to, if any. */ + DataFlowCall asCall() { result = this.asElement() } + + /** Gets the callable that this node corresponds to, if any. */ + DataFlowCallable asCallable() { result = this.asElement() } + + /** Gets a textual representation of this node. */ + string toString() { + result = this.asElement().toString() + or + result = this.asNode().toString() + } + + /** Gets the location of this node. */ + Location getLocation() { + result = this.asElement().getLocation() + or + result = this.asNode().getLocation() + } +} + +/** Provides additional sink specification logic required for annotations. */ +pragma[inline] +predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { + exists(Node n, Top ast | + n = node.asNode() and + ast = mid.asElement() + | + (c = "Parameter" or c = "") and + node.asNode().asParameter() = mid.asElement() + or + c = "" and + n.asExpr().(FieldRead).getField() = ast + ) +} + +/** Provides additional source specification logic required for annotations. */ +pragma[inline] +predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { + exists(FieldWrite fw | + c = "" and + fw.getField() = mid.asElement() and + n.asNode().asExpr() = fw.getRHS() + ) +} diff --git a/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll b/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll index 28de0cf8eed..45b41bff87c 100644 --- a/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll +++ b/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll @@ -11,6 +11,7 @@ private import VirtualDispatch private import semmle.code.java.dataflow.internal.BaseSSA private import semmle.code.java.dataflow.internal.DataFlowUtil private import semmle.code.java.dataflow.internal.DataFlowPrivate +private import semmle.code.java.dataflow.InstanceAccess private import semmle.code.java.Collections private import semmle.code.java.Maps diff --git a/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll index 9ec77acf2c7..44a2d47ca41 100644 --- a/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll @@ -14,6 +14,7 @@ private import semmle.code.java.dataflow.internal.BaseSSA private import semmle.code.java.dataflow.internal.DataFlowUtil private import semmle.code.java.dataflow.internal.DataFlowPrivate private import semmle.code.java.dataflow.internal.ContainerFlow +private import semmle.code.java.dataflow.InstanceAccess /** * Gets a viable dispatch target for `ma`. This is the input dispatch relation. From cc02c95092900962a4c41c3ebd3128484973f61a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Jun 2021 15:58:00 +0200 Subject: [PATCH 140/272] C#: Sync files --- .../dataflow/internal/FlowSummaryImpl.qll | 121 +++++++++++++++++- .../internal/FlowSummaryImplSpecific.qll | 82 +++++++++++- 2 files changed, 194 insertions(+), 9 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index da6f89071ef..22b4b343524 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -9,6 +9,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public +private import DataFlowImplCommon as DataFlowImplCommon /** Provides classes and predicates for defining flow summaries. */ module Public { @@ -178,7 +179,6 @@ module Public { */ module Private { private import Public - private import DataFlowImplCommon as DataFlowImplCommon newtype TSummaryComponent = TContentSummaryComponent(Content c) or @@ -580,6 +580,14 @@ module Private { * summaries into a `SummarizedCallable`s. */ module External { + /** Holds if `spec` is a relevant external specification. */ + private predicate relevantSpec(string spec) { + summaryElement(_, spec, _, _) or + summaryElement(_, _, spec, _) or + sourceElement(_, spec, _) or + sinkElement(_, spec, _) + } + /** Holds if the `n`th component of specification `s` is `c`. */ predicate specSplit(string s, string c, int n) { relevantSpec(s) and s.splitAt(" of ", n) = c } @@ -629,6 +637,8 @@ module Private { or exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos)) or + c = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind()) + or result = interpretComponentSpecific(c) ) } @@ -664,13 +674,13 @@ module Private { } private class SummarizedCallableExternal extends SummarizedCallable { - SummarizedCallableExternal() { externalSummary(this, _, _, _) } + SummarizedCallableExternal() { summaryElement(this, _, _, _) } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { exists(string inSpec, string outSpec, string kind | - externalSummary(this, inSpec, outSpec, kind) and + summaryElement(this, inSpec, outSpec, kind) and interpretSpec(inSpec, 0, input) and interpretSpec(outSpec, 0, output) | @@ -686,6 +696,111 @@ module Private { specSplit(spec, c, _) and not exists(interpretComponent(c)) } + + private predicate inputNeedsReference(string c) { + c = "Argument" or + parseArg(c, _) + } + + private predicate outputNeedsReference(string c) { + c = "Argument" or + parseArg(c, _) or + c = "ReturnValue" + } + + private predicate sourceElementRef(InterpretNode ref, string output, string kind) { + exists(SourceOrSinkElement e | + sourceElement(e, output, kind) and + if outputNeedsReference(specLast(output)) + then viableCallable(ref.asCall()) = any(InterpretNode n | n.asElement() = e).asCallable() + else ref.asElement() = e + ) + } + + private predicate sinkElementRef(InterpretNode ref, string input, string kind) { + exists(SourceOrSinkElement e | + sinkElement(e, input, kind) and + if inputNeedsReference(specLast(input)) + then viableCallable(ref.asCall()) = any(InterpretNode n | n.asElement() = e).asCallable() + else ref.asElement() = e + ) + } + + private predicate interpretOutput(string output, int idx, InterpretNode ref, InterpretNode node) { + sourceElementRef(ref, output, _) and + specLength(output, idx) and + node = ref + or + exists(InterpretNode mid, string c | + interpretOutput(output, idx + 1, ref, mid) and + specSplit(output, c, idx) + | + exists(int pos | + node.asNode() + .(PostUpdateNode) + .getPreUpdateNode() + .(ArgumentNode) + .argumentOf(mid.asCall(), pos) + | + c = "Argument" or parseArg(c, pos) + ) + or + exists(int pos | node.asNode().(ParameterNode).isParameterOf(mid.asCallable(), pos) | + c = "Parameter" or parseParam(c, pos) + ) + or + c = "ReturnValue" and + node.asNode() = getAnOutNode(mid.asCall(), getReturnValueKind()) + or + interpretOutputSpecific(c, mid, node) + ) + } + + private predicate interpretInput(string input, int idx, InterpretNode ref, InterpretNode node) { + sinkElementRef(ref, input, _) and + specLength(input, idx) and + node = ref + or + exists(InterpretNode mid, string c | + interpretInput(input, idx + 1, ref, mid) and + specSplit(input, c, idx) + | + exists(int pos | node.asNode().(ArgumentNode).argumentOf(mid.asCall(), pos) | + c = "Argument" or parseArg(c, pos) + ) + or + exists(ReturnNode ret | + c = "ReturnValue" and + ret = node.asNode() and + ret.getKind() = getReturnValueKind() and + mid.asCallable() = DataFlowImplCommon::getNodeEnclosingCallable(ret) + ) + or + interpretInputSpecific(c, mid, node) + ) + } + + /** + * Holds if `node` is specified as a source with the given kind in a CSV flow + * model. + */ + predicate isSourceNode(InterpretNode node, string kind) { + exists(InterpretNode ref, string output | + sourceElementRef(ref, output, kind) and + interpretOutput(output, 0, ref, node) + ) + } + + /** + * Holds if `node` is specified as a sink with the given kind in a CSV flow + * model. + */ + predicate isSinkNode(InterpretNode node, string kind) { + exists(InterpretNode ref, string input | + sinkElementRef(ref, input, kind) and + interpretInput(input, 0, ref, node) + ) + } } /** Provides a query predicate for outputting a set of relevant flow summaries. */ diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 5568b8d3368..4764ed17c22 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -78,20 +78,15 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { ) } -/** Holds if `spec` is a relevant external specification. */ -predicate relevantSpec(string spec) { none() } - /** * Holds if an external flow summary exists for `c` with input specification * `input`, output specification `output`, and kind `kind`. */ -predicate externalSummary(DataFlowCallable c, string input, string output, string kind) { none() } +predicate summaryElement(DataFlowCallable c, string input, string output, string kind) { none() } /** Gets the summary component for specification component `c`, if any. */ bindingset[c] SummaryComponent interpretComponentSpecific(string c) { - c = "ReturnValue" and result = SummaryComponent::return(any(NormalReturnKind nrk)) - or c = "Element" and result = SummaryComponent::content(any(ElementContent ec)) or exists(Field f | @@ -104,3 +99,78 @@ SummaryComponent interpretComponentSpecific(string c) { result = SummaryComponent::content(any(PropertyContent pc | pc.getProperty() = p)) ) } + +class SourceOrSinkElement = Element; + +/** + * Holds if an external source specification exists for `e` with output specification + * `output` and kind `kind`. + */ +predicate sourceElement(Element e, string output, string kind) { none() } + +/** + * Holds if an external sink specification exists for `n` with input specification + * `input` and kind `kind`. + */ +predicate sinkElement(Element e, string input, string kind) { none() } + +/** Gets the return kind corresponding to specification `"ReturnValue"`. */ +NormalReturnKind getReturnValueKind() { any() } + +private newtype TInterpretNode = + TElement_(Element n) or + TNode_(Node n) or + TDataFlowCall_(DataFlowCall c) + +/** An entity used to interpret a source/sink specification. */ +class InterpretNode extends TInterpretNode { + /** Gets the element that this node corresponds to, if any. */ + SourceOrSinkElement asElement() { this = TElement_(result) } + + /** Gets the data-flow node that this node corresponds to, if any. */ + Node asNode() { this = TNode_(result) } + + /** Gets the call that this node corresponds to, if any. */ + DataFlowCall asCall() { this = TDataFlowCall_(result) } + + /** Gets the callable that this node corresponds to, if any. */ + DataFlowCallable asCallable() { result = this.asElement() } + + /** Gets a textual representation of this node. */ + string toString() { + result = this.asElement().toString() + or + result = this.asNode().toString() + or + result = this.asCall().toString() + } + + /** Gets the location of this node. */ + Location getLocation() { + result = this.asElement().getLocation() + or + result = this.asNode().getLocation() + or + result = this.asCall().getLocation() + } +} + +/** Provides additional sink specification logic required for attributes. */ +predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { + exists(Node n | n = node.asNode() | + (c = "Parameter" or c = "") and + n.asParameter() = mid.asElement() + or + c = "" and + n.asExpr().(AssignableRead).getTarget().getUnboundDeclaration() = mid.asElement() + ) +} + +/** Provides additional sink specification logic required for attributes. */ +predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { + c = "" and + exists(Assignable a | + n.asNode().asExpr() = a.getAnAssignedValue() and + a.getUnboundDeclaration() = mid.asElement() + ) +} From 7e778bc008243f56cd2d8de78b64d161a3ec34ff Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Tue, 27 Apr 2021 18:54:52 +0200 Subject: [PATCH 141/272] Java: Override toString() for statements Additionally remove redundant QLDoc which is inherited anyways. --- java/ql/src/semmle/code/java/Statement.qll | 102 +- .../test/library-tests/JDK/PrintAst.expected | 32 +- .../library-tests/arrays/PrintAst.expected | 8 +- .../collections/PrintAst.expected | 4 +- .../library-tests/comments/PrintAst.expected | 8 +- .../library-tests/constants/PrintAst.expected | 188 +-- .../constructors/PrintAst.expected | 16 +- .../controlflow/basic/bbStmts.expected | 248 ++-- .../basic/bbStrictDominance.expected | 242 ++-- .../controlflow/basic/bbSuccessor.expected | 58 +- .../basic/strictDominance.expected | 1256 ++++++++--------- .../basic/strictPostDominance.expected | 464 +++--- .../controlflow/dominance/dominator.expected | 206 +-- .../dependency/PrintAst.expected | 10 +- .../library-tests/generics/PrintAst.expected | 4 +- .../test/library-tests/guards/guards.expected | 70 +- .../library-tests/guards/guardslogic.expected | 76 +- .../library-tests/guards12/PrintAst.expected | 10 +- .../library-tests/guards12/guard.expected | 2 +- .../java7/MultiCatch/MultiCatch.expected | 8 +- .../MultiCatch/MultiCatchControlFlow.expected | 80 +- .../java7/MultiCatch/PrintAst.expected | 52 +- .../library-tests/javadoc/PrintAst.expected | 6 +- .../LocalVarDeclStmtChildren.expected | 22 +- .../localvars/TypeAccesses.expected | 16 +- .../library-tests/modifiers/PrintAst.expected | 4 +- .../library-tests/printAst/PrintAst.expected | 50 +- .../reflection/PrintAst.expected | 12 +- .../ql/test/library-tests/ssa/ssaDef.expected | 54 +- .../ql/test/library-tests/ssa/ssaPhi.expected | 34 +- .../ql/test/library-tests/ssa/ssaUse.expected | 56 +- .../library-tests/stmts/JumpTargets.expected | 18 +- .../library-tests/stmts/SwitchCases.expected | 12 +- .../CloseReaderTest/TestSucc.expected | 36 +- .../LoopVarReadTest/FalseSuccessors.expected | 2 +- .../LoopVarReadTest/TestSucc.expected | 24 +- .../SaveFileTest/FalseSuccessors.expected | 4 +- .../successors/SaveFileTest/TestSucc.expected | 112 +- .../SchackTest/FalseSuccessors.expected | 10 +- .../successors/SchackTest/TestSucc.expected | 96 +- .../TestBreak/FalseSuccessors.expected | 10 +- .../successors/TestBreak/TestSucc.expected | 200 +-- .../TestContinue/FalseSuccessors.expected | 18 +- .../successors/TestContinue/TestSucc.expected | 134 +- .../TestDeclarations/FalseSuccessors.expected | 4 +- .../TestDeclarations/TestSucc.expected | 70 +- .../TestFinally/FalseSuccessors.expected | 30 +- .../successors/TestFinally/TestSucc.expected | 444 +++--- .../FalseSuccessors.expected | 12 +- .../TestSucc.expected | 212 +-- .../TestLoopBranch/FalseSuccessors.expected | 10 +- .../TestLoopBranch/TestSucc.expected | 286 ++-- .../TestThrow/FalseSuccessors.expected | 24 +- .../successors/TestThrow/TestSucc.expected | 348 ++--- .../successors/TestThrow2/TestSucc.expected | 26 +- .../TestTryCatch/FalseSuccessors.expected | 2 +- .../successors/TestTryCatch/TestSucc.expected | 122 +- .../TestTryWithResources/TestSucc.expected | 42 +- .../typeaccesses/PrintAst.expected | 36 +- .../UnreachableBlocks.expected | 18 +- .../library-tests/varargs/PrintAst.expected | 16 +- .../query-tests/BusyWait/BusyWait.expected | 4 +- .../ConstantLoopCondition.expected | 8 +- .../ContinueInFalseLoop.expected | 6 +- .../Declarations/BreakInSwitchCase.expected | 4 +- .../DoubleCheckedLocking.expected | 6 +- .../Finally/FinallyMayNotComplete.expected | 14 +- .../MissedTernaryOpportunity.expected | 12 +- .../PartiallyMaskedCatch.expected | 12 +- .../query-tests/UseBraces/UseBraces.expected | 28 +- .../returnstatement.expected | 2 +- .../semmle/tests/InfiniteLoop.expected | 2 +- 72 files changed, 2935 insertions(+), 2939 deletions(-) diff --git a/java/ql/src/semmle/code/java/Statement.qll b/java/ql/src/semmle/code/java/Statement.qll index 97a09ac4e6b..12e894cf073 100755 --- a/java/ql/src/semmle/code/java/Statement.qll +++ b/java/ql/src/semmle/code/java/Statement.qll @@ -73,10 +73,10 @@ class BlockStmt extends Stmt, @block { /** Gets the last statement in this block. */ Stmt getLastStmt() { result = getStmt(getNumStmt() - 1) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "{ ... }" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "{ ... }" } + override string getHalsteadID() { result = "BlockStmt" } override string getAPrimaryQlClass() { result = "BlockStmt" } @@ -130,14 +130,14 @@ class IfStmt extends ConditionalStmt, @ifstmt { /** Gets the `else` branch of this `if` statement. */ Stmt getElse() { result.isNthChildOf(this, 2) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "if (...) " + this.getThen().pp() + " else " + this.getElse().pp() or not exists(this.getElse()) and result = "if (...) " + this.getThen().pp() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "if (...)" } + override string getHalsteadID() { result = "IfStmt" } override string getAPrimaryQlClass() { result = "IfStmt" } @@ -201,10 +201,10 @@ class ForStmt extends ConditionalStmt, @forstmt { getCondition().getAChildExpr*() = result.getAnAccess() } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "for (...;...;...) " + this.getStmt().pp() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "for (...)" } + override string getHalsteadID() { result = "ForStmt" } override string getAPrimaryQlClass() { result = "ForStmt" } @@ -221,10 +221,10 @@ class EnhancedForStmt extends Stmt, @enhancedforstmt { /** Gets the body of this enhanced `for` loop. */ Stmt getStmt() { result.getParent() = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ - override string pp() { result = "for (...) " + this.getStmt().pp() } + override string pp() { result = "for (... : ...) " + this.getStmt().pp() } + + override string toString() { result = "for (... : ...)" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ override string getHalsteadID() { result = "EnhancedForStmt" } override string getAPrimaryQlClass() { result = "EnhancedForStmt" } @@ -244,10 +244,10 @@ class WhileStmt extends ConditionalStmt, @whilestmt { */ deprecated override Stmt getTrueSuccessor() { result = getStmt() } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "while (...) " + this.getStmt().pp() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "while (...)" } + override string getHalsteadID() { result = "WhileStmt" } override string getAPrimaryQlClass() { result = "WhileStmt" } @@ -267,10 +267,10 @@ class DoStmt extends ConditionalStmt, @dostmt { */ deprecated override Stmt getTrueSuccessor() { result = getStmt() } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "do " + this.getStmt().pp() + " while (...)" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "do ... while (...)" } + override string getHalsteadID() { result = "DoStmt" } override string getAPrimaryQlClass() { result = "DoStmt" } @@ -356,10 +356,10 @@ class TryStmt extends Stmt, @trystmt { result = getAResourceExpr().getVariable() } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "try " + this.getBlock().pp() + " catch (...)" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "try ..." } + override string getHalsteadID() { result = "TryStmt" } override string getAPrimaryQlClass() { result = "TryStmt" } @@ -387,10 +387,10 @@ class CatchClause extends Stmt, @catchclause { ) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "catch (...) " + this.getBlock().pp() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "catch (...)" } + override string getHalsteadID() { result = "CatchClause" } override string getAPrimaryQlClass() { result = "CatchClause" } @@ -422,10 +422,10 @@ class SwitchStmt extends Stmt, @switchstmt { /** Gets the expression of this `switch` statement. */ Expr getExpr() { result.getParent() = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "switch (...)" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "switch (...)" } + override string getHalsteadID() { result = "SwitchStmt" } override string getAPrimaryQlClass() { result = "SwitchStmt" } @@ -485,10 +485,10 @@ class ConstCase extends SwitchCase { */ Expr getValue(int i) { result.getParent() = this and result.getIndex() = i and i >= 0 } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "case ..." } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "case ..." } + override string getHalsteadID() { result = "ConstCase" } override string getAPrimaryQlClass() { result = "ConstCase" } @@ -498,10 +498,10 @@ class ConstCase extends SwitchCase { class DefaultCase extends SwitchCase { DefaultCase() { not exists(Expr e | e.getParent() = this | e.getIndex() >= 0) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "default" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "default" } + override string getHalsteadID() { result = "DefaultCase" } override string getAPrimaryQlClass() { result = "DefaultCase" } @@ -515,10 +515,10 @@ class SynchronizedStmt extends Stmt, @synchronizedstmt { /** Gets the block of this `synchronized` statement. */ Stmt getBlock() { result.getParent() = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "synchronized (...) " + this.getBlock().pp() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "synchronized (...)" } + override string getHalsteadID() { result = "SynchronizedStmt" } override string getAPrimaryQlClass() { result = "SynchronizedStmt" } @@ -529,10 +529,10 @@ class ReturnStmt extends Stmt, @returnstmt { /** Gets the expression returned by this `return` statement, if any. */ Expr getResult() { result.getParent() = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "return ..." } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "return ..." } + override string getHalsteadID() { result = "ReturnStmt" } override string getAPrimaryQlClass() { result = "ReturnStmt" } @@ -543,10 +543,10 @@ class ThrowStmt extends Stmt, @throwstmt { /** Gets the expression thrown by this `throw` statement. */ Expr getExpr() { result.getParent() = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "throw ..." } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "throw ..." } + override string getHalsteadID() { result = "ThrowStmt" } /** Gets the type of the expression thrown by this `throw` statement. */ @@ -638,12 +638,12 @@ class BreakStmt extends Stmt, @breakstmt { /** Holds if this `break` statement has an explicit label. */ predicate hasLabel() { exists(string s | s = this.getLabel()) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { if this.hasLabel() then result = "break " + this.getLabel() else result = "break" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "break" } + override string getHalsteadID() { result = "BreakStmt" } override string getAPrimaryQlClass() { result = "BreakStmt" } @@ -660,6 +660,8 @@ class YieldStmt extends Stmt, @yieldstmt { override string pp() { result = "yield ..." } + override string toString() { result = "yield ..." } + override string getHalsteadID() { result = "YieldStmt" } override string getAPrimaryQlClass() { result = "YieldStmt" } @@ -673,12 +675,12 @@ class ContinueStmt extends Stmt, @continuestmt { /** Holds if this `continue` statement has an explicit label. */ predicate hasLabel() { exists(string s | s = this.getLabel()) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { if this.hasLabel() then result = "continue " + this.getLabel() else result = "continue" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "continue" } + override string getHalsteadID() { result = "ContinueStmt" } override string getAPrimaryQlClass() { result = "ContinueStmt" } @@ -686,10 +688,10 @@ class ContinueStmt extends Stmt, @continuestmt { /** The empty statement. */ class EmptyStmt extends Stmt, @emptystmt { - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = ";" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = ";" } + override string getHalsteadID() { result = "EmptyStmt" } override string getAPrimaryQlClass() { result = "EmptyStmt" } @@ -704,10 +706,10 @@ class ExprStmt extends Stmt, @exprstmt { /** Gets the expression of this expression statement. */ Expr getExpr() { result.getParent() = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "...;" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "...;" } + override string getHalsteadID() { result = "ExprStmt" } /** Holds if this statement represents a field declaration with an initializer. */ @@ -733,12 +735,12 @@ class LabeledStmt extends Stmt, @labeledstmt { /** Gets the label of this labeled statement. */ string getLabel() { namestrings(result, _, this) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = this.getLabel() + ": " + this.getStmt().pp() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ override string getHalsteadID() { result = this.getLabel() + ":" } + override string toString() { result = "labeled statement" } + override string getAPrimaryQlClass() { result = "LabeledStmt" } } @@ -750,12 +752,12 @@ class AssertStmt extends Stmt, @assertstmt { /** Gets the assertion message expression, if any. */ Expr getMessage() { exprs(result, _, _, this, _) and result.getIndex() = 1 } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { if exists(this.getMessage()) then result = "assert ... : ..." else result = "assert ..." } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "assert ..." } + override string getHalsteadID() { result = "AssertStmt" } override string getAPrimaryQlClass() { result = "AssertStmt" } @@ -775,10 +777,10 @@ class LocalVariableDeclStmt extends Stmt, @localvariabledeclstmt { /** Gets an index of a variable declared in this local variable declaration statement. */ int getAVariableIndex() { exists(getVariable(result)) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "local variable declaration" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "local variable declaration" } + override string getHalsteadID() { result = "LocalVariableDeclStmt" } override string getAPrimaryQlClass() { result = "LocalVariableDeclStmt" } @@ -789,10 +791,10 @@ class LocalClassDeclStmt extends Stmt, @localclassdeclstmt { /** Gets the local class declared by this statement. */ LocalClass getLocalClass() { isLocalClass(result, this) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "local class declaration: " + this.getLocalClass().toString() } - /** This statement's Halstead ID (used to compute Halstead metrics). */ + override string toString() { result = "local class declaration" } + override string getHalsteadID() { result = "LocalClassDeclStmt" } override string getAPrimaryQlClass() { result = "LocalClassDeclStmt" } @@ -829,13 +831,10 @@ class ThisConstructorInvocationStmt extends Stmt, ConstructorCall, @constructori /** Gets the immediately enclosing statement of this constructor invocation. */ override Stmt getEnclosingStmt() { result = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "this(...)" } - /** Gets a printable representation of this statement. */ - override string toString() { result = pp() } + override string toString() { result = "this(...)" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ override string getHalsteadID() { result = "ConstructorInvocationStmt" } override string getAPrimaryQlClass() { result = "ThisConstructorInvocationStmt" } @@ -873,13 +872,10 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr /** Gets the immediately enclosing statement of this constructor invocation. */ override Stmt getEnclosingStmt() { result = this } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { result = "super(...)" } - /** Gets a printable representation of this statement. */ - override string toString() { result = pp() } + override string toString() { result = "super(...)" } - /** This statement's Halstead ID (used to compute Halstead metrics). */ override string getHalsteadID() { result = "SuperConstructorInvocationStmt" } override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" } diff --git a/java/ql/test/library-tests/JDK/PrintAst.expected b/java/ql/test/library-tests/JDK/PrintAst.expected index 74967e122e3..1b3d63c4b74 100644 --- a/java/ql/test/library-tests/JDK/PrintAst.expected +++ b/java/ql/test/library-tests/JDK/PrintAst.expected @@ -7,7 +7,7 @@ jdk/A.java: # 4| 0: [Parameter] args # 4| 0: [ArrayTypeAccess] ...[] # 4| 0: [TypeAccess] String -# 4| 5: [BlockStmt] stmt +# 4| 5: [BlockStmt] { ... } # 7| 2: [Class] B # 8| 2: [Method] main # 8| 3: [TypeAccess] void @@ -15,7 +15,7 @@ jdk/A.java: # 8| 0: [Parameter] args # 8| 0: [ArrayTypeAccess] ...[] # 8| 0: [TypeAccess] String -# 8| 5: [BlockStmt] stmt +# 8| 5: [BlockStmt] { ... } # 11| 3: [Class] C # 12| 2: [Method] main # 12| 3: [TypeAccess] void @@ -23,7 +23,7 @@ jdk/A.java: # 12| 0: [Parameter] args # 12| 0: [ArrayTypeAccess] ...[] # 12| 0: [TypeAccess] String -# 12| 5: [BlockStmt] stmt +# 12| 5: [BlockStmt] { ... } # 15| 4: [Class] D # 16| 2: [Method] main # 16| 3: [TypeAccess] int @@ -31,8 +31,8 @@ jdk/A.java: # 16| 0: [Parameter] args # 16| 0: [ArrayTypeAccess] ...[] # 16| 0: [TypeAccess] String -# 16| 5: [BlockStmt] stmt -# 16| 0: [ReturnStmt] stmt +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... # 16| 0: [IntegerLiteral] 0 # 19| 5: [Class] E # 20| 2: [Method] main @@ -43,14 +43,14 @@ jdk/A.java: # 20| 1: [Parameter] args # 20| 0: [ArrayTypeAccess] ...[] # 20| 0: [TypeAccess] String -# 20| 5: [BlockStmt] stmt +# 20| 5: [BlockStmt] { ... } # 23| 6: [Class] F # 24| 2: [Method] main # 24| 3: [TypeAccess] void #-----| 4: (Parameters) # 24| 0: [Parameter] arg # 24| 0: [TypeAccess] String -# 24| 5: [BlockStmt] stmt +# 24| 5: [BlockStmt] { ... } # 27| 7: [Class] G # 28| 2: [Method] main # 28| 3: [TypeAccess] void @@ -59,7 +59,7 @@ jdk/A.java: # 28| 0: [ArrayTypeAccess] ...[] # 28| 0: [ArrayTypeAccess] ...[] # 28| 0: [TypeAccess] String -# 28| 5: [BlockStmt] stmt +# 28| 5: [BlockStmt] { ... } jdk/SystemGetPropertyCall.java: # 0| [CompilationUnit] SystemGetPropertyCall # 3| 1: [Class] SystemGetPropertyCall @@ -68,30 +68,30 @@ jdk/SystemGetPropertyCall.java: # 4| 0: [StringLiteral] "user.dir" # 6| 4: [Method] a # 6| 3: [TypeAccess] void -# 6| 5: [BlockStmt] stmt -# 7| 0: [ExprStmt] stmt +# 6| 5: [BlockStmt] { ... } +# 7| 0: [ExprStmt] ...; # 7| 0: [MethodAccess] getProperty(...) # 7| -1: [TypeAccess] System # 7| 0: [StringLiteral] "user.dir" # 10| 5: [Method] b # 10| 3: [TypeAccess] void -# 10| 5: [BlockStmt] stmt -# 11| 0: [ExprStmt] stmt +# 10| 5: [BlockStmt] { ... } +# 11| 0: [ExprStmt] ...; # 11| 0: [MethodAccess] getProperty(...) # 11| -1: [TypeAccess] System # 11| 0: [StringLiteral] "user.dir" # 11| 1: [StringLiteral] "HOME" # 14| 6: [Method] c # 14| 3: [TypeAccess] void -# 14| 5: [BlockStmt] stmt -# 15| 0: [ExprStmt] stmt +# 14| 5: [BlockStmt] { ... } +# 15| 0: [ExprStmt] ...; # 15| 0: [MethodAccess] getProperty(...) # 15| -1: [TypeAccess] System # 15| 0: [VarAccess] USER_DIR_PROPERTY # 18| 7: [Method] d # 18| 3: [TypeAccess] void -# 18| 5: [BlockStmt] stmt -# 19| 0: [ExprStmt] stmt +# 18| 5: [BlockStmt] { ... } +# 19| 0: [ExprStmt] ...; # 19| 0: [MethodAccess] getProperty(...) # 19| -1: [TypeAccess] System # 19| 0: [StringLiteral] "random.property" diff --git a/java/ql/test/library-tests/arrays/PrintAst.expected b/java/ql/test/library-tests/arrays/PrintAst.expected index 2fd1eb3d7d8..25edb648e1b 100644 --- a/java/ql/test/library-tests/arrays/PrintAst.expected +++ b/java/ql/test/library-tests/arrays/PrintAst.expected @@ -16,8 +16,8 @@ arrays/B.java: #-----| 4: (Parameters) # 4| 0: [Parameter] a # 4| 0: [TypeAccess] A -# 4| 5: [BlockStmt] stmt -# 5| 0: [LocalVariableDeclStmt] stmt +# 4| 5: [BlockStmt] { ... } +# 5| 0: [LocalVariableDeclStmt] local variable declaration # 5| 0: [ArrayTypeAccess] ...[] # 5| 0: [TypeAccess] A # 5| 1: [LocalVariableDeclExpr] aa @@ -25,7 +25,7 @@ arrays/B.java: # 5| -2: [ArrayInit] {...} # 5| 0: [VarAccess] a # 5| -1: [TypeAccess] A -# 6| 1: [LocalVariableDeclStmt] stmt +# 6| 1: [LocalVariableDeclStmt] local variable declaration # 6| 0: [ArrayTypeAccess] ...[] # 6| 0: [ArrayTypeAccess] ...[] # 6| 0: [TypeAccess] A @@ -36,7 +36,7 @@ arrays/B.java: # 6| 0: [VarAccess] a # 6| -1: [ArrayTypeAccess] ...[] # 6| 0: [TypeAccess] A -# 7| 2: [LocalVariableDeclStmt] stmt +# 7| 2: [LocalVariableDeclStmt] local variable declaration # 7| 0: [ArrayTypeAccess] ...[] # 7| 0: [ArrayTypeAccess] ...[] # 7| 0: [ArrayTypeAccess] ...[] diff --git a/java/ql/test/library-tests/collections/PrintAst.expected b/java/ql/test/library-tests/collections/PrintAst.expected index 0198acb2561..942bfca360e 100644 --- a/java/ql/test/library-tests/collections/PrintAst.expected +++ b/java/ql/test/library-tests/collections/PrintAst.expected @@ -11,8 +11,8 @@ collections/Test.java: # 6| -3: [TypeAccess] LinkedHashMap # 6| 0: [TypeAccess] String # 6| 1: [TypeAccess] Integer -# 8| 4: [BlockStmt] stmt -# 9| 0: [ExprStmt] stmt +# 8| 4: [BlockStmt] { ... } +# 9| 0: [ExprStmt] ...; # 9| 0: [MethodAccess] put(...) # 9| -1: [VarAccess] m # 9| 0: [StringLiteral] "key" diff --git a/java/ql/test/library-tests/comments/PrintAst.expected b/java/ql/test/library-tests/comments/PrintAst.expected index dce19c722e7..be018582311 100644 --- a/java/ql/test/library-tests/comments/PrintAst.expected +++ b/java/ql/test/library-tests/comments/PrintAst.expected @@ -10,10 +10,10 @@ Test.java: # 6| 1: [Javadoc] /** A JavaDoc comment with a single line. */ # 6| 0: [JavadocText] A JavaDoc comment with a single line. # 7| 3: [TypeAccess] void -# 7| 5: [BlockStmt] stmt +# 7| 5: [BlockStmt] { ... } # 21| 3: [Method] test # 21| 3: [TypeAccess] void -# 21| 5: [BlockStmt] stmt +# 21| 5: [BlockStmt] { ... } TestWindows.java: # 0| [CompilationUnit] TestWindows # 5| 1: [Class] TestWindows @@ -26,7 +26,7 @@ TestWindows.java: # 6| 1: [Javadoc] /** A JavaDoc comment with a single line. */ # 6| 0: [JavadocText] A JavaDoc comment with a single line. # 7| 3: [TypeAccess] void -# 7| 5: [BlockStmt] stmt +# 7| 5: [BlockStmt] { ... } # 21| 3: [Method] test # 21| 3: [TypeAccess] void -# 21| 5: [BlockStmt] stmt +# 21| 5: [BlockStmt] { ... } diff --git a/java/ql/test/library-tests/constants/PrintAst.expected b/java/ql/test/library-tests/constants/PrintAst.expected index d2420e71ada..51f079eac2a 100644 --- a/java/ql/test/library-tests/constants/PrintAst.expected +++ b/java/ql/test/library-tests/constants/PrintAst.expected @@ -6,58 +6,58 @@ constants/Constants.java: #-----| 4: (Parameters) # 4| 0: [Parameter] notConstant # 4| 0: [TypeAccess] int -# 4| 5: [BlockStmt] stmt -# 5| 0: [LocalVariableDeclStmt] stmt +# 4| 5: [BlockStmt] { ... } +# 5| 0: [LocalVariableDeclStmt] local variable declaration # 5| 0: [TypeAccess] int # 5| 1: [LocalVariableDeclExpr] sfield # 5| 0: [VarAccess] Initializers.SFIELD # 5| -1: [TypeAccess] Initializers -# 6| 1: [LocalVariableDeclStmt] stmt +# 6| 1: [LocalVariableDeclStmt] local variable declaration # 6| 0: [TypeAccess] int # 6| 1: [LocalVariableDeclExpr] ifield # 6| 0: [VarAccess] new Initializers(...).IFIELD # 6| -1: [ClassInstanceExpr] new Initializers(...) # 6| -3: [TypeAccess] Initializers -# 9| 2: [LocalVariableDeclStmt] stmt +# 9| 2: [LocalVariableDeclStmt] local variable declaration # 9| 0: [TypeAccess] Object # 9| 1: [LocalVariableDeclExpr] staticObjectField # 9| 0: [VarAccess] Initializers.SFIELD_OBJECT # 9| -1: [TypeAccess] Initializers -# 11| 3: [LocalVariableDeclStmt] stmt +# 11| 3: [LocalVariableDeclStmt] local variable declaration # 11| 0: [TypeAccess] int # 11| 1: [LocalVariableDeclExpr] x # 11| 0: [IntegerLiteral] 3 -# 12| 4: [LocalVariableDeclStmt] stmt +# 12| 4: [LocalVariableDeclStmt] local variable declaration # 12| 0: [TypeAccess] int # 12| 1: [LocalVariableDeclExpr] y # 12| 0: [VarAccess] x -# 13| 5: [LocalVariableDeclStmt] stmt +# 13| 5: [LocalVariableDeclStmt] local variable declaration # 13| 0: [TypeAccess] int # 13| 1: [LocalVariableDeclExpr] z # 13| 0: [VarAccess] y -# 15| 6: [LocalVariableDeclStmt] stmt +# 15| 6: [LocalVariableDeclStmt] local variable declaration # 15| 0: [TypeAccess] int # 15| 1: [LocalVariableDeclExpr] binop # 15| 0: [AddExpr] ... + ... # 15| 0: [VarAccess] Initializers.SFIELD # 15| -1: [TypeAccess] Initializers # 15| 1: [IntegerLiteral] 1 -# 16| 7: [LocalVariableDeclStmt] stmt +# 16| 7: [LocalVariableDeclStmt] local variable declaration # 16| 0: [TypeAccess] int # 16| 1: [LocalVariableDeclExpr] binopNonConst # 16| 0: [AddExpr] ... + ... # 16| 0: [VarAccess] Initializers.SFIELD # 16| -1: [TypeAccess] Initializers # 16| 1: [VarAccess] notConstant -# 18| 8: [LocalVariableDeclStmt] stmt +# 18| 8: [LocalVariableDeclStmt] local variable declaration # 18| 0: [TypeAccess] int # 18| 1: [LocalVariableDeclExpr] paren # 18| 0: [IntegerLiteral] 12 -# 19| 9: [LocalVariableDeclStmt] stmt +# 19| 9: [LocalVariableDeclStmt] local variable declaration # 19| 0: [TypeAccess] String # 19| 1: [LocalVariableDeclExpr] string # 19| 0: [StringLiteral] "a string" -# 20| 10: [LocalVariableDeclStmt] stmt +# 20| 10: [LocalVariableDeclStmt] local variable declaration # 20| 0: [TypeAccess] int # 20| 1: [LocalVariableDeclExpr] ternary # 20| 0: [ConditionalExpr] ...?...:... @@ -66,7 +66,7 @@ constants/Constants.java: # 20| 1: [IntegerLiteral] 5 # 20| 1: [IntegerLiteral] 1 # 20| 2: [IntegerLiteral] 2 -# 22| 11: [ReturnStmt] stmt +# 22| 11: [ReturnStmt] return ... constants/Initializers.java: # 0| [CompilationUnit] Initializers # 3| 1: [Class] Initializers @@ -79,22 +79,22 @@ constants/Initializers.java: # 8| 5: [FieldDeclaration] int IFIELD2, ...; # 8| -1: [TypeAccess] int # 10| 6: [Constructor] Initializers -# 10| 5: [BlockStmt] stmt -# 12| 2: [ExprStmt] stmt +# 10| 5: [BlockStmt] { ... } +# 12| 2: [ExprStmt] ...; # 12| 0: [AssignExpr] ...=... # 12| 0: [VarAccess] IFIELD2 # 12| 1: [IntegerLiteral] 22 # 15| 7: [Method] stuff # 15| 3: [TypeAccess] void -# 15| 5: [BlockStmt] stmt -# 16| 0: [LocalVariableDeclStmt] stmt +# 15| 5: [BlockStmt] { ... } +# 16| 0: [LocalVariableDeclStmt] local variable declaration # 16| 0: [TypeAccess] int # 16| 1: [LocalVariableDeclExpr] x # 16| 0: [IntegerLiteral] 300 -# 17| 1: [LocalVariableDeclStmt] stmt +# 17| 1: [LocalVariableDeclStmt] local variable declaration # 17| 0: [TypeAccess] int # 17| 1: [LocalVariableDeclExpr] y -# 18| 2: [ExprStmt] stmt +# 18| 2: [ExprStmt] ...; # 18| 0: [AssignExpr] ...=... # 18| 0: [VarAccess] y # 18| 1: [IntegerLiteral] 400 @@ -111,21 +111,21 @@ constants/Initializers.java: # 26| 12: [FieldDeclaration] int f, ...; # 26| -1: [TypeAccess] int # 26| 0: [IntegerLiteral] 4 -# 28| 13: [BlockStmt] stmt -# 30| 0: [ExprStmt] stmt +# 28| 13: [BlockStmt] { ... } +# 30| 0: [ExprStmt] ...; # 30| 0: [AssignExpr] ...=... # 30| 0: [VarAccess] fsf # 30| 1: [IntegerLiteral] 42 -# 31| 1: [ExprStmt] stmt +# 31| 1: [ExprStmt] ...; # 31| 0: [AssignExpr] ...=... # 31| 0: [VarAccess] sf # 31| 1: [IntegerLiteral] 42 -# 34| 14: [BlockStmt] stmt -# 36| 0: [ExprStmt] stmt +# 34| 14: [BlockStmt] { ... } +# 36| 0: [ExprStmt] ...; # 36| 0: [AssignExpr] ...=... # 36| 0: [VarAccess] ff # 36| 1: [IntegerLiteral] 42 -# 37| 1: [ExprStmt] stmt +# 37| 1: [ExprStmt] ...; # 37| 0: [AssignExpr] ...=... # 37| 0: [VarAccess] f # 37| 1: [IntegerLiteral] 42 @@ -143,372 +143,372 @@ constants/Values.java: #-----| 4: (Parameters) # 8| 0: [Parameter] notConstant # 8| 0: [TypeAccess] int -# 8| 5: [BlockStmt] stmt -# 9| 0: [LocalVariableDeclStmt] stmt +# 8| 5: [BlockStmt] { ... } +# 9| 0: [LocalVariableDeclStmt] local variable declaration # 9| 0: [TypeAccess] int # 9| 1: [LocalVariableDeclExpr] int_literal # 9| 0: [IntegerLiteral] 42 -# 10| 1: [LocalVariableDeclStmt] stmt +# 10| 1: [LocalVariableDeclStmt] local variable declaration # 10| 0: [TypeAccess] int # 10| 1: [LocalVariableDeclExpr] negative_int_literal # 10| 0: [IntegerLiteral] -2147483648 -# 11| 2: [LocalVariableDeclStmt] stmt +# 11| 2: [LocalVariableDeclStmt] local variable declaration # 11| 0: [TypeAccess] int # 11| 1: [LocalVariableDeclExpr] octal_literal # 11| 0: [IntegerLiteral] 052 -# 12| 3: [LocalVariableDeclStmt] stmt +# 12| 3: [LocalVariableDeclStmt] local variable declaration # 12| 0: [TypeAccess] int # 12| 1: [LocalVariableDeclExpr] negative_octal_literal # 12| 0: [MinusExpr] -... # 12| 0: [IntegerLiteral] 052 -# 13| 4: [LocalVariableDeclStmt] stmt +# 13| 4: [LocalVariableDeclStmt] local variable declaration # 13| 0: [TypeAccess] int # 13| 1: [LocalVariableDeclExpr] hex_literal # 13| 0: [IntegerLiteral] 0x2A -# 14| 5: [LocalVariableDeclStmt] stmt +# 14| 5: [LocalVariableDeclStmt] local variable declaration # 14| 0: [TypeAccess] int # 14| 1: [LocalVariableDeclExpr] negative_hex_literal # 14| 0: [MinusExpr] -... # 14| 0: [IntegerLiteral] 0x2A -# 15| 6: [LocalVariableDeclStmt] stmt +# 15| 6: [LocalVariableDeclStmt] local variable declaration # 15| 0: [TypeAccess] int # 15| 1: [LocalVariableDeclExpr] hex_literal_underscores # 15| 0: [IntegerLiteral] 0x2_A -# 16| 7: [LocalVariableDeclStmt] stmt +# 16| 7: [LocalVariableDeclStmt] local variable declaration # 16| 0: [TypeAccess] int # 16| 1: [LocalVariableDeclExpr] binary_literal # 16| 0: [IntegerLiteral] 0b101010 -# 17| 8: [LocalVariableDeclStmt] stmt +# 17| 8: [LocalVariableDeclStmt] local variable declaration # 17| 0: [TypeAccess] int # 17| 1: [LocalVariableDeclExpr] negative_binary_literal # 17| 0: [MinusExpr] -... # 17| 0: [IntegerLiteral] 0b101010 -# 18| 9: [LocalVariableDeclStmt] stmt +# 18| 9: [LocalVariableDeclStmt] local variable declaration # 18| 0: [TypeAccess] int # 18| 1: [LocalVariableDeclExpr] binary_literal_underscores # 18| 0: [IntegerLiteral] 0b1_0101_0 -# 19| 10: [LocalVariableDeclStmt] stmt +# 19| 10: [LocalVariableDeclStmt] local variable declaration # 19| 0: [TypeAccess] char # 19| 1: [LocalVariableDeclExpr] char_literal # 19| 0: [CharacterLiteral] '*' -# 20| 11: [LocalVariableDeclStmt] stmt +# 20| 11: [LocalVariableDeclStmt] local variable declaration # 20| 0: [TypeAccess] long # 20| 1: [LocalVariableDeclExpr] long_literal # 20| 0: [LongLiteral] 42L -# 21| 12: [LocalVariableDeclStmt] stmt +# 21| 12: [LocalVariableDeclStmt] local variable declaration # 21| 0: [TypeAccess] boolean # 21| 1: [LocalVariableDeclExpr] boolean_literal # 21| 0: [BooleanLiteral] true -# 22| 13: [LocalVariableDeclStmt] stmt +# 22| 13: [LocalVariableDeclStmt] local variable declaration # 22| 0: [TypeAccess] Integer # 22| 1: [LocalVariableDeclExpr] boxed_int # 22| 0: [ClassInstanceExpr] new Integer(...) # 22| -3: [TypeAccess] Integer # 22| 0: [IntegerLiteral] 42 -# 23| 14: [LocalVariableDeclStmt] stmt +# 23| 14: [LocalVariableDeclStmt] local variable declaration # 23| 0: [TypeAccess] int # 23| 1: [LocalVariableDeclExpr] parameter # 23| 0: [VarAccess] notConstant -# 25| 15: [LocalVariableDeclStmt] stmt +# 25| 15: [LocalVariableDeclStmt] local variable declaration # 25| 0: [TypeAccess] int # 25| 1: [LocalVariableDeclExpr] cast # 25| 0: [CastExpr] (...)... # 25| 0: [TypeAccess] int # 25| 1: [IntegerLiteral] 42 -# 26| 16: [LocalVariableDeclStmt] stmt +# 26| 16: [LocalVariableDeclStmt] local variable declaration # 26| 0: [TypeAccess] char # 26| 1: [LocalVariableDeclExpr] downcast # 26| 0: [CastExpr] (...)... # 26| 0: [TypeAccess] char # 26| 1: [IntegerLiteral] 42 -# 27| 17: [LocalVariableDeclStmt] stmt +# 27| 17: [LocalVariableDeclStmt] local variable declaration # 27| 0: [TypeAccess] byte # 27| 1: [LocalVariableDeclExpr] downcast_byte_1 # 27| 0: [CastExpr] (...)... # 27| 0: [TypeAccess] byte # 27| 1: [MinusExpr] -... # 27| 0: [IntegerLiteral] 42 -# 28| 18: [LocalVariableDeclStmt] stmt +# 28| 18: [LocalVariableDeclStmt] local variable declaration # 28| 0: [TypeAccess] byte # 28| 1: [LocalVariableDeclExpr] downcast_byte_2 # 28| 0: [CastExpr] (...)... # 28| 0: [TypeAccess] byte # 28| 1: [IntegerLiteral] 42 -# 29| 19: [LocalVariableDeclStmt] stmt +# 29| 19: [LocalVariableDeclStmt] local variable declaration # 29| 0: [TypeAccess] byte # 29| 1: [LocalVariableDeclExpr] downcast_byte_3 # 29| 0: [CastExpr] (...)... # 29| 0: [TypeAccess] byte # 29| 1: [IntegerLiteral] 298 -# 30| 20: [LocalVariableDeclStmt] stmt +# 30| 20: [LocalVariableDeclStmt] local variable declaration # 30| 0: [TypeAccess] byte # 30| 1: [LocalVariableDeclExpr] downcast_byte_4 # 30| 0: [CastExpr] (...)... # 30| 0: [TypeAccess] byte # 30| 1: [IntegerLiteral] 214 -# 31| 21: [LocalVariableDeclStmt] stmt +# 31| 21: [LocalVariableDeclStmt] local variable declaration # 31| 0: [TypeAccess] byte # 31| 1: [LocalVariableDeclExpr] downcast_byte_5 # 31| 0: [CastExpr] (...)... # 31| 0: [TypeAccess] byte # 31| 1: [MinusExpr] -... # 31| 0: [IntegerLiteral] 214 -# 32| 22: [LocalVariableDeclStmt] stmt +# 32| 22: [LocalVariableDeclStmt] local variable declaration # 32| 0: [TypeAccess] short # 32| 1: [LocalVariableDeclExpr] downcast_short # 32| 0: [CastExpr] (...)... # 32| 0: [TypeAccess] short # 32| 1: [IntegerLiteral] 32768 -# 33| 23: [LocalVariableDeclStmt] stmt +# 33| 23: [LocalVariableDeclStmt] local variable declaration # 33| 0: [TypeAccess] int # 33| 1: [LocalVariableDeclExpr] cast_of_non_constant # 33| 0: [CastExpr] (...)... # 33| 0: [TypeAccess] int # 33| 1: [CharacterLiteral] '*' -# 34| 24: [LocalVariableDeclStmt] stmt +# 34| 24: [LocalVariableDeclStmt] local variable declaration # 34| 0: [TypeAccess] long # 34| 1: [LocalVariableDeclExpr] cast_to_long # 34| 0: [CastExpr] (...)... # 34| 0: [TypeAccess] long # 34| 1: [IntegerLiteral] 42 -# 36| 25: [LocalVariableDeclStmt] stmt +# 36| 25: [LocalVariableDeclStmt] local variable declaration # 36| 0: [TypeAccess] int # 36| 1: [LocalVariableDeclExpr] unary_plus # 36| 0: [PlusExpr] +... # 36| 0: [IntegerLiteral] 42 -# 37| 26: [LocalVariableDeclStmt] stmt +# 37| 26: [LocalVariableDeclStmt] local variable declaration # 37| 0: [TypeAccess] int # 37| 1: [LocalVariableDeclExpr] parameter_plus # 37| 0: [PlusExpr] +... # 37| 0: [VarAccess] notConstant -# 39| 27: [LocalVariableDeclStmt] stmt +# 39| 27: [LocalVariableDeclStmt] local variable declaration # 39| 0: [TypeAccess] int # 39| 1: [LocalVariableDeclExpr] unary_minus # 39| 0: [MinusExpr] -... # 39| 0: [IntegerLiteral] 42 -# 40| 28: [LocalVariableDeclStmt] stmt +# 40| 28: [LocalVariableDeclStmt] local variable declaration # 40| 0: [TypeAccess] int # 40| 1: [LocalVariableDeclExpr] parameter_minus # 40| 0: [MinusExpr] -... # 40| 0: [VarAccess] notConstant -# 42| 29: [LocalVariableDeclStmt] stmt +# 42| 29: [LocalVariableDeclStmt] local variable declaration # 42| 0: [TypeAccess] boolean # 42| 1: [LocalVariableDeclExpr] not # 42| 0: [LogNotExpr] !... # 42| 0: [BooleanLiteral] true -# 43| 30: [LocalVariableDeclStmt] stmt +# 43| 30: [LocalVariableDeclStmt] local variable declaration # 43| 0: [TypeAccess] int # 43| 1: [LocalVariableDeclExpr] bitwise_not # 43| 0: [BitNotExpr] ~... # 43| 0: [IntegerLiteral] 0 -# 45| 31: [LocalVariableDeclStmt] stmt +# 45| 31: [LocalVariableDeclStmt] local variable declaration # 45| 0: [TypeAccess] int # 45| 1: [LocalVariableDeclExpr] mul # 45| 0: [MulExpr] ... * ... # 45| 0: [IntegerLiteral] 7 # 45| 1: [IntegerLiteral] 9 -# 46| 32: [LocalVariableDeclStmt] stmt +# 46| 32: [LocalVariableDeclStmt] local variable declaration # 46| 0: [TypeAccess] int # 46| 1: [LocalVariableDeclExpr] mul_parameter # 46| 0: [MulExpr] ... * ... # 46| 0: [VarAccess] notConstant # 46| 1: [VarAccess] notConstant -# 48| 33: [LocalVariableDeclStmt] stmt +# 48| 33: [LocalVariableDeclStmt] local variable declaration # 48| 0: [TypeAccess] int # 48| 1: [LocalVariableDeclExpr] div # 48| 0: [DivExpr] ... / ... # 48| 0: [IntegerLiteral] 168 # 48| 1: [IntegerLiteral] 4 -# 49| 34: [LocalVariableDeclStmt] stmt +# 49| 34: [LocalVariableDeclStmt] local variable declaration # 49| 0: [TypeAccess] int # 49| 1: [LocalVariableDeclExpr] div_by_zero # 49| 0: [DivExpr] ... / ... # 49| 0: [IntegerLiteral] 42 # 49| 1: [IntegerLiteral] 0 -# 50| 35: [LocalVariableDeclStmt] stmt +# 50| 35: [LocalVariableDeclStmt] local variable declaration # 50| 0: [TypeAccess] int # 50| 1: [LocalVariableDeclExpr] div_parameter # 50| 0: [DivExpr] ... / ... # 50| 0: [VarAccess] notConstant # 50| 1: [VarAccess] notConstant -# 52| 36: [LocalVariableDeclStmt] stmt +# 52| 36: [LocalVariableDeclStmt] local variable declaration # 52| 0: [TypeAccess] int # 52| 1: [LocalVariableDeclExpr] rem # 52| 0: [RemExpr] ... % ... # 52| 0: [IntegerLiteral] 168 # 52| 1: [IntegerLiteral] 63 -# 53| 37: [LocalVariableDeclStmt] stmt +# 53| 37: [LocalVariableDeclStmt] local variable declaration # 53| 0: [TypeAccess] int # 53| 1: [LocalVariableDeclExpr] rem_by_zero # 53| 0: [RemExpr] ... % ... # 53| 0: [IntegerLiteral] 42 # 53| 1: [IntegerLiteral] 0 -# 54| 38: [LocalVariableDeclStmt] stmt +# 54| 38: [LocalVariableDeclStmt] local variable declaration # 54| 0: [TypeAccess] int # 54| 1: [LocalVariableDeclExpr] rem_parameter # 54| 0: [RemExpr] ... % ... # 54| 0: [VarAccess] notConstant # 54| 1: [VarAccess] notConstant -# 56| 39: [LocalVariableDeclStmt] stmt +# 56| 39: [LocalVariableDeclStmt] local variable declaration # 56| 0: [TypeAccess] int # 56| 1: [LocalVariableDeclExpr] plus # 56| 0: [AddExpr] ... + ... # 56| 0: [IntegerLiteral] 10 # 56| 1: [IntegerLiteral] 32 -# 57| 40: [LocalVariableDeclStmt] stmt +# 57| 40: [LocalVariableDeclStmt] local variable declaration # 57| 0: [TypeAccess] int # 57| 1: [LocalVariableDeclExpr] plus_parameter # 57| 0: [AddExpr] ... + ... # 57| 0: [VarAccess] notConstant # 57| 1: [VarAccess] notConstant -# 59| 41: [LocalVariableDeclStmt] stmt +# 59| 41: [LocalVariableDeclStmt] local variable declaration # 59| 0: [TypeAccess] int # 59| 1: [LocalVariableDeclExpr] minus # 59| 0: [SubExpr] ... - ... # 59| 0: [IntegerLiteral] 168 # 59| 1: [IntegerLiteral] 126 -# 60| 42: [LocalVariableDeclStmt] stmt +# 60| 42: [LocalVariableDeclStmt] local variable declaration # 60| 0: [TypeAccess] int # 60| 1: [LocalVariableDeclExpr] minus_parameter # 60| 0: [SubExpr] ... - ... # 60| 0: [VarAccess] notConstant # 60| 1: [VarAccess] notConstant -# 62| 43: [LocalVariableDeclStmt] stmt +# 62| 43: [LocalVariableDeclStmt] local variable declaration # 62| 0: [TypeAccess] int # 62| 1: [LocalVariableDeclExpr] lshift # 62| 0: [LShiftExpr] ... << ... # 62| 0: [IntegerLiteral] 21 # 62| 1: [IntegerLiteral] 2 -# 63| 44: [LocalVariableDeclStmt] stmt +# 63| 44: [LocalVariableDeclStmt] local variable declaration # 63| 0: [TypeAccess] int # 63| 1: [LocalVariableDeclExpr] lshift_parameter # 63| 0: [LShiftExpr] ... << ... # 63| 0: [VarAccess] notConstant # 63| 1: [VarAccess] notConstant -# 65| 45: [LocalVariableDeclStmt] stmt +# 65| 45: [LocalVariableDeclStmt] local variable declaration # 65| 0: [TypeAccess] int # 65| 1: [LocalVariableDeclExpr] rshift # 65| 0: [RShiftExpr] ... >> ... # 65| 0: [MinusExpr] -... # 65| 0: [IntegerLiteral] 1 # 65| 1: [IntegerLiteral] 2 -# 66| 46: [LocalVariableDeclStmt] stmt +# 66| 46: [LocalVariableDeclStmt] local variable declaration # 66| 0: [TypeAccess] int # 66| 1: [LocalVariableDeclExpr] urshift # 66| 0: [URShiftExpr] ... >>> ... # 66| 0: [MinusExpr] -... # 66| 0: [IntegerLiteral] 1 # 66| 1: [IntegerLiteral] 1 -# 67| 47: [LocalVariableDeclStmt] stmt +# 67| 47: [LocalVariableDeclStmt] local variable declaration # 67| 0: [TypeAccess] int # 67| 1: [LocalVariableDeclExpr] bitwise_and # 67| 0: [AndBitwiseExpr] ... & ... # 67| 0: [IntegerLiteral] 63 # 67| 1: [IntegerLiteral] 42 -# 68| 48: [LocalVariableDeclStmt] stmt +# 68| 48: [LocalVariableDeclStmt] local variable declaration # 68| 0: [TypeAccess] int # 68| 1: [LocalVariableDeclExpr] bitwise_or # 68| 0: [OrBitwiseExpr] ... | ... # 68| 0: [IntegerLiteral] 32 # 68| 1: [IntegerLiteral] 42 -# 69| 49: [LocalVariableDeclStmt] stmt +# 69| 49: [LocalVariableDeclStmt] local variable declaration # 69| 0: [TypeAccess] int # 69| 1: [LocalVariableDeclExpr] bitwise_xor # 69| 0: [XorBitwiseExpr] ... ^ ... # 69| 0: [IntegerLiteral] 48 # 69| 1: [IntegerLiteral] 26 -# 70| 50: [LocalVariableDeclStmt] stmt +# 70| 50: [LocalVariableDeclStmt] local variable declaration # 70| 0: [TypeAccess] boolean # 70| 1: [LocalVariableDeclExpr] and # 70| 0: [AndLogicalExpr] ... && ... # 70| 0: [BooleanLiteral] true # 70| 1: [BooleanLiteral] false -# 71| 51: [LocalVariableDeclStmt] stmt +# 71| 51: [LocalVariableDeclStmt] local variable declaration # 71| 0: [TypeAccess] boolean # 71| 1: [LocalVariableDeclExpr] or # 71| 0: [OrLogicalExpr] ... || ... # 71| 0: [BooleanLiteral] true # 71| 1: [BooleanLiteral] false -# 72| 52: [LocalVariableDeclStmt] stmt +# 72| 52: [LocalVariableDeclStmt] local variable declaration # 72| 0: [TypeAccess] boolean # 72| 1: [LocalVariableDeclExpr] lt # 72| 0: [LTExpr] ... < ... # 72| 0: [IntegerLiteral] 42 # 72| 1: [IntegerLiteral] 42 -# 73| 53: [LocalVariableDeclStmt] stmt +# 73| 53: [LocalVariableDeclStmt] local variable declaration # 73| 0: [TypeAccess] boolean # 73| 1: [LocalVariableDeclExpr] le # 73| 0: [LEExpr] ... <= ... # 73| 0: [IntegerLiteral] 42 # 73| 1: [IntegerLiteral] 42 -# 74| 54: [LocalVariableDeclStmt] stmt +# 74| 54: [LocalVariableDeclStmt] local variable declaration # 74| 0: [TypeAccess] boolean # 74| 1: [LocalVariableDeclExpr] gt # 74| 0: [GTExpr] ... > ... # 74| 0: [IntegerLiteral] 42 # 74| 1: [IntegerLiteral] 42 -# 75| 55: [LocalVariableDeclStmt] stmt +# 75| 55: [LocalVariableDeclStmt] local variable declaration # 75| 0: [TypeAccess] boolean # 75| 1: [LocalVariableDeclExpr] gle # 75| 0: [GEExpr] ... >= ... # 75| 0: [IntegerLiteral] 42 # 75| 1: [IntegerLiteral] 42 -# 76| 56: [LocalVariableDeclStmt] stmt +# 76| 56: [LocalVariableDeclStmt] local variable declaration # 76| 0: [TypeAccess] boolean # 76| 1: [LocalVariableDeclExpr] eq # 76| 0: [EQExpr] ... == ... # 76| 0: [IntegerLiteral] 42 # 76| 1: [IntegerLiteral] 42 -# 77| 57: [LocalVariableDeclStmt] stmt +# 77| 57: [LocalVariableDeclStmt] local variable declaration # 77| 0: [TypeAccess] boolean # 77| 1: [LocalVariableDeclExpr] ne # 77| 0: [NEExpr] ... != ... # 77| 0: [IntegerLiteral] 42 # 77| 1: [IntegerLiteral] 42 -# 78| 58: [LocalVariableDeclStmt] stmt +# 78| 58: [LocalVariableDeclStmt] local variable declaration # 78| 0: [TypeAccess] boolean # 78| 1: [LocalVariableDeclExpr] ter # 78| 0: [ConditionalExpr] ...?...:... # 78| 0: [BooleanLiteral] true # 78| 1: [BooleanLiteral] false # 78| 2: [BooleanLiteral] true -# 80| 59: [LocalVariableDeclStmt] stmt +# 80| 59: [LocalVariableDeclStmt] local variable declaration # 80| 0: [TypeAccess] boolean # 80| 1: [LocalVariableDeclExpr] seq # 80| 0: [EQExpr] ... == ... # 80| 0: [StringLiteral] "foo" # 80| 1: [StringLiteral] "foo" -# 81| 60: [LocalVariableDeclStmt] stmt +# 81| 60: [LocalVariableDeclStmt] local variable declaration # 81| 0: [TypeAccess] boolean # 81| 1: [LocalVariableDeclExpr] sneq # 81| 0: [NEExpr] ... != ... # 81| 0: [StringLiteral] "foo" # 81| 1: [StringLiteral] "foo" -# 83| 61: [LocalVariableDeclStmt] stmt +# 83| 61: [LocalVariableDeclStmt] local variable declaration # 83| 0: [TypeAccess] int # 83| 1: [LocalVariableDeclExpr] par # 83| 0: [IntegerLiteral] 42 -# 84| 62: [LocalVariableDeclStmt] stmt +# 84| 62: [LocalVariableDeclStmt] local variable declaration # 84| 0: [TypeAccess] int # 84| 1: [LocalVariableDeclExpr] par_not_constant # 84| 0: [VarAccess] notConstant -# 86| 63: [LocalVariableDeclStmt] stmt +# 86| 63: [LocalVariableDeclStmt] local variable declaration # 86| 0: [TypeAccess] int # 86| 1: [LocalVariableDeclExpr] var_field # 86| 0: [VarAccess] final_field -# 87| 64: [LocalVariableDeclStmt] stmt +# 87| 64: [LocalVariableDeclStmt] local variable declaration # 87| 0: [TypeAccess] int # 87| 1: [LocalVariableDeclExpr] final_local # 87| 0: [IntegerLiteral] 42 -# 88| 65: [LocalVariableDeclStmt] stmt +# 88| 65: [LocalVariableDeclStmt] local variable declaration # 88| 0: [TypeAccess] int # 88| 1: [LocalVariableDeclExpr] var_local # 88| 0: [VarAccess] final_local -# 89| 66: [LocalVariableDeclStmt] stmt +# 89| 66: [LocalVariableDeclStmt] local variable declaration # 89| 0: [TypeAccess] int # 89| 1: [LocalVariableDeclExpr] var_param # 89| 0: [VarAccess] notConstant -# 90| 67: [LocalVariableDeclStmt] stmt +# 90| 67: [LocalVariableDeclStmt] local variable declaration # 90| 0: [TypeAccess] int # 90| 1: [LocalVariableDeclExpr] var_nonfinald_local # 90| 0: [VarAccess] var_field diff --git a/java/ql/test/library-tests/constructors/PrintAst.expected b/java/ql/test/library-tests/constructors/PrintAst.expected index 6dc34314b0b..db3907670c4 100644 --- a/java/ql/test/library-tests/constructors/PrintAst.expected +++ b/java/ql/test/library-tests/constructors/PrintAst.expected @@ -2,22 +2,22 @@ constructors/A.java: # 0| [CompilationUnit] A # 3| 1: [Class] A # 4| 3: [Constructor] A -# 4| 5: [BlockStmt] stmt +# 4| 5: [BlockStmt] { ... } # 5| 0: [ThisConstructorInvocationStmt] this(...) # 5| 0: [IntegerLiteral] 42 # 8| 4: [Constructor] A #-----| 4: (Parameters) # 8| 0: [Parameter] i # 8| 0: [TypeAccess] int -# 8| 5: [BlockStmt] stmt +# 8| 5: [BlockStmt] { ... } # 10| 5: [Method] main # 10| 3: [TypeAccess] void #-----| 4: (Parameters) # 10| 0: [Parameter] args # 10| 0: [ArrayTypeAccess] ...[] # 10| 0: [TypeAccess] String -# 10| 5: [BlockStmt] stmt -# 11| 0: [ExprStmt] stmt +# 10| 5: [BlockStmt] { ... } +# 11| 0: [ExprStmt] ...; # 11| 0: [ClassInstanceExpr] new A(...) # 11| -3: [TypeAccess] A # 14| 6: [FieldDeclaration] String STATIC, ...; @@ -26,14 +26,14 @@ constructors/A.java: # 15| 7: [FieldDeclaration] String INSTANCE, ...; # 15| -1: [TypeAccess] String # 15| 0: [StringLiteral] "instance string" -# 17| 8: [BlockStmt] stmt -# 18| 0: [ExprStmt] stmt +# 17| 8: [BlockStmt] { ... } +# 18| 0: [ExprStmt] ...; # 18| 0: [MethodAccess] println(...) # 18| -1: [VarAccess] System.out # 18| -1: [TypeAccess] System # 18| 0: [StringLiteral] "" -# 21| 9: [BlockStmt] stmt -# 22| 0: [ExprStmt] stmt +# 21| 9: [BlockStmt] { ... } +# 22| 0: [ExprStmt] ...; # 22| 0: [MethodAccess] println(...) # 22| -1: [VarAccess] System.out # 22| -1: [TypeAccess] System diff --git a/java/ql/test/library-tests/controlflow/basic/bbStmts.expected b/java/ql/test/library-tests/controlflow/basic/bbStmts.expected index 1b239e1dd29..a23a14afbe9 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStmts.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbStmts.expected @@ -1,136 +1,136 @@ -| Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | Test | 2 | -| Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | stmt | 0 | -| Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | super(...) | 1 | +| Test.java:3:14:3:17 | { ... } | Test.java:3:14:3:17 | Test | 2 | +| Test.java:3:14:3:17 | { ... } | Test.java:3:14:3:17 | super(...) | 1 | +| Test.java:3:14:3:17 | { ... } | Test.java:3:14:3:17 | { ... } | 0 | | Test.java:4:14:4:17 | test | Test.java:4:14:4:17 | test | 0 | -| Test.java:4:21:76:2 | stmt | Test.java:4:21:76:2 | stmt | 0 | -| Test.java:4:21:76:2 | stmt | Test.java:5:3:5:12 | stmt | 1 | -| Test.java:4:21:76:2 | stmt | Test.java:5:7:5:11 | x | 3 | -| Test.java:4:21:76:2 | stmt | Test.java:5:11:5:11 | 0 | 2 | -| Test.java:4:21:76:2 | stmt | Test.java:6:3:6:14 | stmt | 4 | -| Test.java:4:21:76:2 | stmt | Test.java:6:8:6:13 | y | 6 | -| Test.java:4:21:76:2 | stmt | Test.java:6:12:6:13 | 50 | 5 | -| Test.java:4:21:76:2 | stmt | Test.java:7:3:7:12 | stmt | 7 | -| Test.java:4:21:76:2 | stmt | Test.java:7:7:7:11 | z | 9 | -| Test.java:4:21:76:2 | stmt | Test.java:7:11:7:11 | 0 | 8 | -| Test.java:4:21:76:2 | stmt | Test.java:8:3:8:12 | stmt | 10 | -| Test.java:4:21:76:2 | stmt | Test.java:8:7:8:11 | w | 12 | -| Test.java:4:21:76:2 | stmt | Test.java:8:11:8:11 | 0 | 11 | -| Test.java:4:21:76:2 | stmt | Test.java:11:3:11:12 | stmt | 13 | -| Test.java:4:21:76:2 | stmt | Test.java:11:7:11:7 | x | 14 | -| Test.java:4:21:76:2 | stmt | Test.java:11:7:11:11 | ... > ... | 16 | -| Test.java:4:21:76:2 | stmt | Test.java:11:11:11:11 | 0 | 15 | -| Test.java:11:14:14:3 | stmt | Test.java:11:14:14:3 | stmt | 0 | -| Test.java:11:14:14:3 | stmt | Test.java:12:4:12:9 | ...=... | 3 | -| Test.java:11:14:14:3 | stmt | Test.java:12:4:12:10 | stmt | 1 | -| Test.java:11:14:14:3 | stmt | Test.java:12:8:12:9 | 20 | 2 | -| Test.java:11:14:14:3 | stmt | Test.java:13:4:13:9 | ...=... | 6 | -| Test.java:11:14:14:3 | stmt | Test.java:13:4:13:10 | stmt | 4 | -| Test.java:11:14:14:3 | stmt | Test.java:13:8:13:9 | 10 | 5 | -| Test.java:14:10:16:3 | stmt | Test.java:14:10:16:3 | stmt | 0 | -| Test.java:14:10:16:3 | stmt | Test.java:15:4:15:9 | ...=... | 3 | -| Test.java:14:10:16:3 | stmt | Test.java:15:4:15:10 | stmt | 1 | -| Test.java:14:10:16:3 | stmt | Test.java:15:8:15:9 | 30 | 2 | -| Test.java:18:3:18:8 | stmt | Test.java:18:3:18:7 | ...=... | 2 | -| Test.java:18:3:18:8 | stmt | Test.java:18:3:18:8 | stmt | 0 | -| Test.java:18:3:18:8 | stmt | Test.java:18:7:18:7 | 0 | 1 | -| Test.java:18:3:18:8 | stmt | Test.java:21:3:21:11 | stmt | 3 | -| Test.java:18:3:18:8 | stmt | Test.java:21:6:21:6 | x | 4 | -| Test.java:18:3:18:8 | stmt | Test.java:21:6:21:10 | ... < ... | 6 | -| Test.java:18:3:18:8 | stmt | Test.java:21:10:21:10 | 0 | 5 | -| Test.java:22:4:22:10 | stmt | Test.java:22:4:22:9 | ...=... | 2 | -| Test.java:22:4:22:10 | stmt | Test.java:22:4:22:10 | stmt | 0 | -| Test.java:22:4:22:10 | stmt | Test.java:22:8:22:9 | 40 | 1 | -| Test.java:22:4:22:10 | stmt | Test.java:27:3:27:8 | ...=... | 5 | -| Test.java:22:4:22:10 | stmt | Test.java:27:3:27:9 | stmt | 3 | -| Test.java:22:4:22:10 | stmt | Test.java:27:7:27:8 | 10 | 4 | -| Test.java:22:4:22:10 | stmt | Test.java:30:3:30:13 | stmt | 6 | -| Test.java:22:4:22:10 | stmt | Test.java:30:7:30:7 | x | 7 | -| Test.java:22:4:22:10 | stmt | Test.java:30:7:30:12 | ... == ... | 9 | -| Test.java:22:4:22:10 | stmt | Test.java:30:12:30:12 | 0 | 8 | -| Test.java:24:4:24:10 | stmt | Test.java:24:4:24:10 | stmt | 0 | -| Test.java:30:15:33:3 | stmt | Test.java:30:15:33:3 | stmt | 0 | -| Test.java:30:15:33:3 | stmt | Test.java:31:4:31:9 | ...=... | 3 | -| Test.java:30:15:33:3 | stmt | Test.java:31:4:31:10 | stmt | 1 | -| Test.java:30:15:33:3 | stmt | Test.java:31:8:31:9 | 60 | 2 | -| Test.java:30:15:33:3 | stmt | Test.java:32:4:32:9 | ...=... | 6 | -| Test.java:30:15:33:3 | stmt | Test.java:32:4:32:10 | stmt | 4 | -| Test.java:30:15:33:3 | stmt | Test.java:32:8:32:9 | 10 | 5 | -| Test.java:35:3:35:9 | stmt | Test.java:35:3:35:8 | ...=... | 2 | -| Test.java:35:3:35:9 | stmt | Test.java:35:3:35:9 | stmt | 0 | -| Test.java:35:3:35:9 | stmt | Test.java:35:7:35:8 | 20 | 1 | -| Test.java:35:3:35:9 | stmt | Test.java:38:3:38:14 | stmt | 3 | +| Test.java:4:21:76:2 | { ... } | Test.java:4:21:76:2 | { ... } | 0 | +| Test.java:4:21:76:2 | { ... } | Test.java:5:3:5:12 | local variable declaration | 1 | +| Test.java:4:21:76:2 | { ... } | Test.java:5:7:5:11 | x | 3 | +| Test.java:4:21:76:2 | { ... } | Test.java:5:11:5:11 | 0 | 2 | +| Test.java:4:21:76:2 | { ... } | Test.java:6:3:6:14 | local variable declaration | 4 | +| Test.java:4:21:76:2 | { ... } | Test.java:6:8:6:13 | y | 6 | +| Test.java:4:21:76:2 | { ... } | Test.java:6:12:6:13 | 50 | 5 | +| Test.java:4:21:76:2 | { ... } | Test.java:7:3:7:12 | local variable declaration | 7 | +| Test.java:4:21:76:2 | { ... } | Test.java:7:7:7:11 | z | 9 | +| Test.java:4:21:76:2 | { ... } | Test.java:7:11:7:11 | 0 | 8 | +| Test.java:4:21:76:2 | { ... } | Test.java:8:3:8:12 | local variable declaration | 10 | +| Test.java:4:21:76:2 | { ... } | Test.java:8:7:8:11 | w | 12 | +| Test.java:4:21:76:2 | { ... } | Test.java:8:11:8:11 | 0 | 11 | +| Test.java:4:21:76:2 | { ... } | Test.java:11:3:11:12 | if (...) | 13 | +| Test.java:4:21:76:2 | { ... } | Test.java:11:7:11:7 | x | 14 | +| Test.java:4:21:76:2 | { ... } | Test.java:11:7:11:11 | ... > ... | 16 | +| Test.java:4:21:76:2 | { ... } | Test.java:11:11:11:11 | 0 | 15 | +| Test.java:11:14:14:3 | { ... } | Test.java:11:14:14:3 | { ... } | 0 | +| Test.java:11:14:14:3 | { ... } | Test.java:12:4:12:9 | ...=... | 3 | +| Test.java:11:14:14:3 | { ... } | Test.java:12:4:12:10 | ...; | 1 | +| Test.java:11:14:14:3 | { ... } | Test.java:12:8:12:9 | 20 | 2 | +| Test.java:11:14:14:3 | { ... } | Test.java:13:4:13:9 | ...=... | 6 | +| Test.java:11:14:14:3 | { ... } | Test.java:13:4:13:10 | ...; | 4 | +| Test.java:11:14:14:3 | { ... } | Test.java:13:8:13:9 | 10 | 5 | +| Test.java:14:10:16:3 | { ... } | Test.java:14:10:16:3 | { ... } | 0 | +| Test.java:14:10:16:3 | { ... } | Test.java:15:4:15:9 | ...=... | 3 | +| Test.java:14:10:16:3 | { ... } | Test.java:15:4:15:10 | ...; | 1 | +| Test.java:14:10:16:3 | { ... } | Test.java:15:8:15:9 | 30 | 2 | +| Test.java:18:3:18:8 | ...; | Test.java:18:3:18:7 | ...=... | 2 | +| Test.java:18:3:18:8 | ...; | Test.java:18:3:18:8 | ...; | 0 | +| Test.java:18:3:18:8 | ...; | Test.java:18:7:18:7 | 0 | 1 | +| Test.java:18:3:18:8 | ...; | Test.java:21:3:21:11 | if (...) | 3 | +| Test.java:18:3:18:8 | ...; | Test.java:21:6:21:6 | x | 4 | +| Test.java:18:3:18:8 | ...; | Test.java:21:6:21:10 | ... < ... | 6 | +| Test.java:18:3:18:8 | ...; | Test.java:21:10:21:10 | 0 | 5 | +| Test.java:22:4:22:10 | ...; | Test.java:22:4:22:9 | ...=... | 2 | +| Test.java:22:4:22:10 | ...; | Test.java:22:4:22:10 | ...; | 0 | +| Test.java:22:4:22:10 | ...; | Test.java:22:8:22:9 | 40 | 1 | +| Test.java:22:4:22:10 | ...; | Test.java:27:3:27:8 | ...=... | 5 | +| Test.java:22:4:22:10 | ...; | Test.java:27:3:27:9 | ...; | 3 | +| Test.java:22:4:22:10 | ...; | Test.java:27:7:27:8 | 10 | 4 | +| Test.java:22:4:22:10 | ...; | Test.java:30:3:30:13 | if (...) | 6 | +| Test.java:22:4:22:10 | ...; | Test.java:30:7:30:7 | x | 7 | +| Test.java:22:4:22:10 | ...; | Test.java:30:7:30:12 | ... == ... | 9 | +| Test.java:22:4:22:10 | ...; | Test.java:30:12:30:12 | 0 | 8 | +| Test.java:24:4:24:10 | return ... | Test.java:24:4:24:10 | return ... | 0 | +| Test.java:30:15:33:3 | { ... } | Test.java:30:15:33:3 | { ... } | 0 | +| Test.java:30:15:33:3 | { ... } | Test.java:31:4:31:9 | ...=... | 3 | +| Test.java:30:15:33:3 | { ... } | Test.java:31:4:31:10 | ...; | 1 | +| Test.java:30:15:33:3 | { ... } | Test.java:31:8:31:9 | 60 | 2 | +| Test.java:30:15:33:3 | { ... } | Test.java:32:4:32:9 | ...=... | 6 | +| Test.java:30:15:33:3 | { ... } | Test.java:32:4:32:10 | ...; | 4 | +| Test.java:30:15:33:3 | { ... } | Test.java:32:8:32:9 | 10 | 5 | +| Test.java:35:3:35:9 | ...; | Test.java:35:3:35:8 | ...=... | 2 | +| Test.java:35:3:35:9 | ...; | Test.java:35:3:35:9 | ...; | 0 | +| Test.java:35:3:35:9 | ...; | Test.java:35:7:35:8 | 20 | 1 | +| Test.java:35:3:35:9 | ...; | Test.java:38:3:38:14 | while (...) | 3 | | Test.java:38:9:38:9 | x | Test.java:38:9:38:9 | x | 0 | | Test.java:38:9:38:9 | x | Test.java:38:9:38:13 | ... > ... | 2 | | Test.java:38:9:38:9 | x | Test.java:38:13:38:13 | 0 | 1 | -| Test.java:38:16:41:3 | stmt | Test.java:38:16:41:3 | stmt | 0 | -| Test.java:38:16:41:3 | stmt | Test.java:39:4:39:9 | ...=... | 3 | -| Test.java:38:16:41:3 | stmt | Test.java:39:4:39:10 | stmt | 1 | -| Test.java:38:16:41:3 | stmt | Test.java:39:8:39:9 | 10 | 2 | -| Test.java:38:16:41:3 | stmt | Test.java:40:4:40:4 | x | 5 | -| Test.java:38:16:41:3 | stmt | Test.java:40:4:40:6 | ...-- | 6 | -| Test.java:38:16:41:3 | stmt | Test.java:40:4:40:7 | stmt | 4 | -| Test.java:43:3:43:9 | stmt | Test.java:43:3:43:8 | ...=... | 2 | -| Test.java:43:3:43:9 | stmt | Test.java:43:3:43:9 | stmt | 0 | -| Test.java:43:3:43:9 | stmt | Test.java:43:7:43:8 | 30 | 1 | -| Test.java:43:3:43:9 | stmt | Test.java:46:3:46:29 | stmt | 3 | -| Test.java:43:3:43:9 | stmt | Test.java:46:11:46:15 | j | 5 | -| Test.java:43:3:43:9 | stmt | Test.java:46:15:46:15 | 0 | 4 | +| Test.java:38:16:41:3 | { ... } | Test.java:38:16:41:3 | { ... } | 0 | +| Test.java:38:16:41:3 | { ... } | Test.java:39:4:39:9 | ...=... | 3 | +| Test.java:38:16:41:3 | { ... } | Test.java:39:4:39:10 | ...; | 1 | +| Test.java:38:16:41:3 | { ... } | Test.java:39:8:39:9 | 10 | 2 | +| Test.java:38:16:41:3 | { ... } | Test.java:40:4:40:4 | x | 5 | +| Test.java:38:16:41:3 | { ... } | Test.java:40:4:40:6 | ...-- | 6 | +| Test.java:38:16:41:3 | { ... } | Test.java:40:4:40:7 | ...; | 4 | +| Test.java:43:3:43:9 | ...; | Test.java:43:3:43:8 | ...=... | 2 | +| Test.java:43:3:43:9 | ...; | Test.java:43:3:43:9 | ...; | 0 | +| Test.java:43:3:43:9 | ...; | Test.java:43:7:43:8 | 30 | 1 | +| Test.java:43:3:43:9 | ...; | Test.java:46:3:46:29 | for (...) | 3 | +| Test.java:43:3:43:9 | ...; | Test.java:46:11:46:15 | j | 5 | +| Test.java:43:3:43:9 | ...; | Test.java:46:15:46:15 | 0 | 4 | | Test.java:46:18:46:18 | j | Test.java:46:18:46:18 | j | 0 | | Test.java:46:18:46:18 | j | Test.java:46:18:46:23 | ... < ... | 2 | | Test.java:46:18:46:18 | j | Test.java:46:22:46:23 | 10 | 1 | -| Test.java:46:31:49:3 | stmt | Test.java:46:26:46:26 | j | 7 | -| Test.java:46:31:49:3 | stmt | Test.java:46:26:46:28 | ...++ | 8 | -| Test.java:46:31:49:3 | stmt | Test.java:46:31:49:3 | stmt | 0 | -| Test.java:46:31:49:3 | stmt | Test.java:47:4:47:8 | ...=... | 3 | -| Test.java:46:31:49:3 | stmt | Test.java:47:4:47:9 | stmt | 1 | -| Test.java:46:31:49:3 | stmt | Test.java:47:8:47:8 | 0 | 2 | -| Test.java:46:31:49:3 | stmt | Test.java:48:4:48:9 | ...=... | 6 | -| Test.java:46:31:49:3 | stmt | Test.java:48:4:48:10 | stmt | 4 | -| Test.java:46:31:49:3 | stmt | Test.java:48:8:48:9 | 10 | 5 | -| Test.java:51:3:51:9 | stmt | Test.java:51:3:51:8 | ...=... | 2 | -| Test.java:51:3:51:9 | stmt | Test.java:51:3:51:9 | stmt | 0 | -| Test.java:51:3:51:9 | stmt | Test.java:51:7:51:8 | 40 | 1 | -| Test.java:51:3:51:9 | stmt | Test.java:54:3:54:29 | stmt | 3 | -| Test.java:51:3:51:9 | stmt | Test.java:54:11:54:15 | j | 5 | -| Test.java:51:3:51:9 | stmt | Test.java:54:15:54:15 | 0 | 4 | +| Test.java:46:31:49:3 | { ... } | Test.java:46:26:46:26 | j | 7 | +| Test.java:46:31:49:3 | { ... } | Test.java:46:26:46:28 | ...++ | 8 | +| Test.java:46:31:49:3 | { ... } | Test.java:46:31:49:3 | { ... } | 0 | +| Test.java:46:31:49:3 | { ... } | Test.java:47:4:47:8 | ...=... | 3 | +| Test.java:46:31:49:3 | { ... } | Test.java:47:4:47:9 | ...; | 1 | +| Test.java:46:31:49:3 | { ... } | Test.java:47:8:47:8 | 0 | 2 | +| Test.java:46:31:49:3 | { ... } | Test.java:48:4:48:9 | ...=... | 6 | +| Test.java:46:31:49:3 | { ... } | Test.java:48:4:48:10 | ...; | 4 | +| Test.java:46:31:49:3 | { ... } | Test.java:48:8:48:9 | 10 | 5 | +| Test.java:51:3:51:9 | ...; | Test.java:51:3:51:8 | ...=... | 2 | +| Test.java:51:3:51:9 | ...; | Test.java:51:3:51:9 | ...; | 0 | +| Test.java:51:3:51:9 | ...; | Test.java:51:7:51:8 | 40 | 1 | +| Test.java:51:3:51:9 | ...; | Test.java:54:3:54:29 | for (...) | 3 | +| Test.java:51:3:51:9 | ...; | Test.java:54:11:54:15 | j | 5 | +| Test.java:51:3:51:9 | ...; | Test.java:54:15:54:15 | 0 | 4 | | Test.java:54:18:54:18 | j | Test.java:54:18:54:18 | j | 0 | | Test.java:54:18:54:18 | j | Test.java:54:18:54:23 | ... < ... | 2 | | Test.java:54:18:54:18 | j | Test.java:54:22:54:23 | 10 | 1 | | Test.java:54:26:54:26 | j | Test.java:54:26:54:26 | j | 0 | | Test.java:54:26:54:26 | j | Test.java:54:26:54:28 | ...++ | 1 | -| Test.java:54:31:68:3 | stmt | Test.java:54:31:68:3 | stmt | 0 | -| Test.java:54:31:68:3 | stmt | Test.java:55:4:55:9 | ...=... | 3 | -| Test.java:54:31:68:3 | stmt | Test.java:55:4:55:10 | stmt | 1 | -| Test.java:54:31:68:3 | stmt | Test.java:55:8:55:9 | 30 | 2 | -| Test.java:54:31:68:3 | stmt | Test.java:56:4:56:12 | stmt | 4 | -| Test.java:54:31:68:3 | stmt | Test.java:56:7:56:7 | z | 5 | -| Test.java:54:31:68:3 | stmt | Test.java:56:7:56:11 | ... > ... | 7 | -| Test.java:54:31:68:3 | stmt | Test.java:56:11:56:11 | 0 | 6 | -| Test.java:57:5:57:13 | stmt | Test.java:57:5:57:13 | stmt | 0 | -| Test.java:57:5:57:13 | stmt | Test.java:57:8:57:8 | y | 1 | -| Test.java:57:5:57:13 | stmt | Test.java:57:8:57:12 | ... > ... | 3 | -| Test.java:57:5:57:13 | stmt | Test.java:57:12:57:12 | 0 | 2 | -| Test.java:57:15:60:5 | stmt | Test.java:57:15:60:5 | stmt | 0 | -| Test.java:57:15:60:5 | stmt | Test.java:58:6:58:10 | ...=... | 3 | -| Test.java:57:15:60:5 | stmt | Test.java:58:6:58:11 | stmt | 1 | -| Test.java:57:15:60:5 | stmt | Test.java:58:10:58:10 | 0 | 2 | -| Test.java:57:15:60:5 | stmt | Test.java:59:6:59:11 | stmt | 4 | -| Test.java:60:12:62:5 | stmt | Test.java:60:12:62:5 | stmt | 0 | -| Test.java:60:12:62:5 | stmt | Test.java:61:6:61:11 | ...=... | 3 | -| Test.java:60:12:62:5 | stmt | Test.java:61:6:61:12 | stmt | 1 | -| Test.java:60:12:62:5 | stmt | Test.java:61:10:61:11 | 20 | 2 | -| Test.java:60:12:62:5 | stmt | Test.java:67:4:67:8 | ...=... | 6 | -| Test.java:60:12:62:5 | stmt | Test.java:67:4:67:9 | stmt | 4 | -| Test.java:60:12:62:5 | stmt | Test.java:67:8:67:8 | 0 | 5 | -| Test.java:63:9:66:4 | stmt | Test.java:63:9:66:4 | stmt | 0 | -| Test.java:63:9:66:4 | stmt | Test.java:64:5:64:10 | ...=... | 3 | -| Test.java:63:9:66:4 | stmt | Test.java:64:5:64:11 | stmt | 1 | -| Test.java:63:9:66:4 | stmt | Test.java:64:9:64:10 | 10 | 2 | -| Test.java:63:9:66:4 | stmt | Test.java:65:5:65:13 | stmt | 4 | -| Test.java:70:3:70:9 | stmt | Test.java:70:3:70:8 | ...=... | 2 | -| Test.java:70:3:70:9 | stmt | Test.java:70:3:70:9 | stmt | 0 | -| Test.java:70:3:70:9 | stmt | Test.java:70:7:70:8 | 50 | 1 | -| Test.java:70:3:70:9 | stmt | Test.java:74:3:74:8 | ...=... | 5 | -| Test.java:70:3:70:9 | stmt | Test.java:74:3:74:9 | stmt | 3 | -| Test.java:70:3:70:9 | stmt | Test.java:74:7:74:8 | 40 | 4 | -| Test.java:70:3:70:9 | stmt | Test.java:75:3:75:9 | stmt | 6 | +| Test.java:54:31:68:3 | { ... } | Test.java:54:31:68:3 | { ... } | 0 | +| Test.java:54:31:68:3 | { ... } | Test.java:55:4:55:9 | ...=... | 3 | +| Test.java:54:31:68:3 | { ... } | Test.java:55:4:55:10 | ...; | 1 | +| Test.java:54:31:68:3 | { ... } | Test.java:55:8:55:9 | 30 | 2 | +| Test.java:54:31:68:3 | { ... } | Test.java:56:4:56:12 | if (...) | 4 | +| Test.java:54:31:68:3 | { ... } | Test.java:56:7:56:7 | z | 5 | +| Test.java:54:31:68:3 | { ... } | Test.java:56:7:56:11 | ... > ... | 7 | +| Test.java:54:31:68:3 | { ... } | Test.java:56:11:56:11 | 0 | 6 | +| Test.java:57:5:57:13 | if (...) | Test.java:57:5:57:13 | if (...) | 0 | +| Test.java:57:5:57:13 | if (...) | Test.java:57:8:57:8 | y | 1 | +| Test.java:57:5:57:13 | if (...) | Test.java:57:8:57:12 | ... > ... | 3 | +| Test.java:57:5:57:13 | if (...) | Test.java:57:12:57:12 | 0 | 2 | +| Test.java:57:15:60:5 | { ... } | Test.java:57:15:60:5 | { ... } | 0 | +| Test.java:57:15:60:5 | { ... } | Test.java:58:6:58:10 | ...=... | 3 | +| Test.java:57:15:60:5 | { ... } | Test.java:58:6:58:11 | ...; | 1 | +| Test.java:57:15:60:5 | { ... } | Test.java:58:10:58:10 | 0 | 2 | +| Test.java:57:15:60:5 | { ... } | Test.java:59:6:59:11 | break | 4 | +| Test.java:60:12:62:5 | { ... } | Test.java:60:12:62:5 | { ... } | 0 | +| Test.java:60:12:62:5 | { ... } | Test.java:61:6:61:11 | ...=... | 3 | +| Test.java:60:12:62:5 | { ... } | Test.java:61:6:61:12 | ...; | 1 | +| Test.java:60:12:62:5 | { ... } | Test.java:61:10:61:11 | 20 | 2 | +| Test.java:60:12:62:5 | { ... } | Test.java:67:4:67:8 | ...=... | 6 | +| Test.java:60:12:62:5 | { ... } | Test.java:67:4:67:9 | ...; | 4 | +| Test.java:60:12:62:5 | { ... } | Test.java:67:8:67:8 | 0 | 5 | +| Test.java:63:9:66:4 | { ... } | Test.java:63:9:66:4 | { ... } | 0 | +| Test.java:63:9:66:4 | { ... } | Test.java:64:5:64:10 | ...=... | 3 | +| Test.java:63:9:66:4 | { ... } | Test.java:64:5:64:11 | ...; | 1 | +| Test.java:63:9:66:4 | { ... } | Test.java:64:9:64:10 | 10 | 2 | +| Test.java:63:9:66:4 | { ... } | Test.java:65:5:65:13 | continue | 4 | +| Test.java:70:3:70:9 | ...; | Test.java:70:3:70:8 | ...=... | 2 | +| Test.java:70:3:70:9 | ...; | Test.java:70:3:70:9 | ...; | 0 | +| Test.java:70:3:70:9 | ...; | Test.java:70:7:70:8 | 50 | 1 | +| Test.java:70:3:70:9 | ...; | Test.java:74:3:74:8 | ...=... | 5 | +| Test.java:70:3:70:9 | ...; | Test.java:74:3:74:9 | ...; | 3 | +| Test.java:70:3:70:9 | ...; | Test.java:74:7:74:8 | 40 | 4 | +| Test.java:70:3:70:9 | ...; | Test.java:75:3:75:9 | return ... | 6 | diff --git a/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected b/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected index db369433527..cc15fb63a29 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected @@ -1,127 +1,127 @@ -| Test.java:4:21:76:2 | stmt | Test.java:4:14:4:17 | test | -| Test.java:4:21:76:2 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:38:9:38:9 | x | -| Test.java:4:21:76:2 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:46:18:46:18 | j | -| Test.java:4:21:76:2 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:54:18:54:18 | j | -| Test.java:4:21:76:2 | stmt | Test.java:54:26:54:26 | j | -| Test.java:4:21:76:2 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:4:14:4:17 | test | -| Test.java:18:3:18:8 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:38:9:38:9 | x | -| Test.java:18:3:18:8 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:46:18:46:18 | j | -| Test.java:18:3:18:8 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:54:18:54:18 | j | -| Test.java:18:3:18:8 | stmt | Test.java:54:26:54:26 | j | -| Test.java:18:3:18:8 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:38:9:38:9 | x | -| Test.java:22:4:22:10 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:46:18:46:18 | j | -| Test.java:22:4:22:10 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:54:18:54:18 | j | -| Test.java:22:4:22:10 | stmt | Test.java:54:26:54:26 | j | -| Test.java:22:4:22:10 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:38:9:38:9 | x | -| Test.java:35:3:35:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:46:18:46:18 | j | -| Test.java:35:3:35:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:54:18:54:18 | j | -| Test.java:35:3:35:9 | stmt | Test.java:54:26:54:26 | j | -| Test.java:35:3:35:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | stmt | -| Test.java:38:9:38:9 | x | Test.java:43:3:43:9 | stmt | +| Test.java:4:21:76:2 | { ... } | Test.java:4:14:4:17 | test | +| Test.java:4:21:76:2 | { ... } | Test.java:11:14:14:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:14:10:16:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:18:3:18:8 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:22:4:22:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:24:4:24:10 | return ... | +| Test.java:4:21:76:2 | { ... } | Test.java:30:15:33:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:35:3:35:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:38:9:38:9 | x | +| Test.java:4:21:76:2 | { ... } | Test.java:38:16:41:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:43:3:43:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:46:18:46:18 | j | +| Test.java:4:21:76:2 | { ... } | Test.java:46:31:49:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:51:3:51:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:54:18:54:18 | j | +| Test.java:4:21:76:2 | { ... } | Test.java:54:26:54:26 | j | +| Test.java:4:21:76:2 | { ... } | Test.java:54:31:68:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:57:5:57:13 | if (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:57:15:60:5 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:60:12:62:5 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:63:9:66:4 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:70:3:70:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:4:14:4:17 | test | +| Test.java:18:3:18:8 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:24:4:24:10 | return ... | +| Test.java:18:3:18:8 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:38:9:38:9 | x | +| Test.java:18:3:18:8 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:46:18:46:18 | j | +| Test.java:18:3:18:8 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:54:18:54:18 | j | +| Test.java:18:3:18:8 | ...; | Test.java:54:26:54:26 | j | +| Test.java:18:3:18:8 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:18:3:18:8 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:38:9:38:9 | x | +| Test.java:22:4:22:10 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:46:18:46:18 | j | +| Test.java:22:4:22:10 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:54:18:54:18 | j | +| Test.java:22:4:22:10 | ...; | Test.java:54:26:54:26 | j | +| Test.java:22:4:22:10 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:22:4:22:10 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:38:9:38:9 | x | +| Test.java:35:3:35:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:46:18:46:18 | j | +| Test.java:35:3:35:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:54:18:54:18 | j | +| Test.java:35:3:35:9 | ...; | Test.java:54:26:54:26 | j | +| Test.java:35:3:35:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:35:3:35:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:43:3:43:9 | ...; | | Test.java:38:9:38:9 | x | Test.java:46:18:46:18 | j | -| Test.java:38:9:38:9 | x | Test.java:46:31:49:3 | stmt | -| Test.java:38:9:38:9 | x | Test.java:51:3:51:9 | stmt | +| Test.java:38:9:38:9 | x | Test.java:46:31:49:3 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:51:3:51:9 | ...; | | Test.java:38:9:38:9 | x | Test.java:54:18:54:18 | j | | Test.java:38:9:38:9 | x | Test.java:54:26:54:26 | j | -| Test.java:38:9:38:9 | x | Test.java:54:31:68:3 | stmt | -| Test.java:38:9:38:9 | x | Test.java:57:5:57:13 | stmt | -| Test.java:38:9:38:9 | x | Test.java:57:15:60:5 | stmt | -| Test.java:38:9:38:9 | x | Test.java:60:12:62:5 | stmt | -| Test.java:38:9:38:9 | x | Test.java:63:9:66:4 | stmt | -| Test.java:38:9:38:9 | x | Test.java:70:3:70:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:46:18:46:18 | j | -| Test.java:43:3:43:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:54:18:54:18 | j | -| Test.java:43:3:43:9 | stmt | Test.java:54:26:54:26 | j | -| Test.java:43:3:43:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:46:18:46:18 | j | Test.java:46:31:49:3 | stmt | -| Test.java:46:18:46:18 | j | Test.java:51:3:51:9 | stmt | +| Test.java:38:9:38:9 | x | Test.java:54:31:68:3 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:57:5:57:13 | if (...) | +| Test.java:38:9:38:9 | x | Test.java:57:15:60:5 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:60:12:62:5 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:63:9:66:4 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:70:3:70:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:46:18:46:18 | j | +| Test.java:43:3:43:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:54:18:54:18 | j | +| Test.java:43:3:43:9 | ...; | Test.java:54:26:54:26 | j | +| Test.java:43:3:43:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:43:3:43:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:46:18:46:18 | j | Test.java:46:31:49:3 | { ... } | +| Test.java:46:18:46:18 | j | Test.java:51:3:51:9 | ...; | | Test.java:46:18:46:18 | j | Test.java:54:18:54:18 | j | | Test.java:46:18:46:18 | j | Test.java:54:26:54:26 | j | -| Test.java:46:18:46:18 | j | Test.java:54:31:68:3 | stmt | -| Test.java:46:18:46:18 | j | Test.java:57:5:57:13 | stmt | -| Test.java:46:18:46:18 | j | Test.java:57:15:60:5 | stmt | -| Test.java:46:18:46:18 | j | Test.java:60:12:62:5 | stmt | -| Test.java:46:18:46:18 | j | Test.java:63:9:66:4 | stmt | -| Test.java:46:18:46:18 | j | Test.java:70:3:70:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:54:18:54:18 | j | -| Test.java:51:3:51:9 | stmt | Test.java:54:26:54:26 | j | -| Test.java:51:3:51:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:70:3:70:9 | stmt | +| Test.java:46:18:46:18 | j | Test.java:54:31:68:3 | { ... } | +| Test.java:46:18:46:18 | j | Test.java:57:5:57:13 | if (...) | +| Test.java:46:18:46:18 | j | Test.java:57:15:60:5 | { ... } | +| Test.java:46:18:46:18 | j | Test.java:60:12:62:5 | { ... } | +| Test.java:46:18:46:18 | j | Test.java:63:9:66:4 | { ... } | +| Test.java:46:18:46:18 | j | Test.java:70:3:70:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:54:18:54:18 | j | +| Test.java:51:3:51:9 | ...; | Test.java:54:26:54:26 | j | +| Test.java:51:3:51:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:51:3:51:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:70:3:70:9 | ...; | | Test.java:54:18:54:18 | j | Test.java:54:26:54:26 | j | -| Test.java:54:18:54:18 | j | Test.java:54:31:68:3 | stmt | -| Test.java:54:18:54:18 | j | Test.java:57:5:57:13 | stmt | -| Test.java:54:18:54:18 | j | Test.java:57:15:60:5 | stmt | -| Test.java:54:18:54:18 | j | Test.java:60:12:62:5 | stmt | -| Test.java:54:18:54:18 | j | Test.java:63:9:66:4 | stmt | -| Test.java:54:18:54:18 | j | Test.java:70:3:70:9 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:54:26:54:26 | j | -| Test.java:54:31:68:3 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:60:12:62:5 | stmt | +| Test.java:54:18:54:18 | j | Test.java:54:31:68:3 | { ... } | +| Test.java:54:18:54:18 | j | Test.java:57:5:57:13 | if (...) | +| Test.java:54:18:54:18 | j | Test.java:57:15:60:5 | { ... } | +| Test.java:54:18:54:18 | j | Test.java:60:12:62:5 | { ... } | +| Test.java:54:18:54:18 | j | Test.java:63:9:66:4 | { ... } | +| Test.java:54:18:54:18 | j | Test.java:70:3:70:9 | ...; | +| Test.java:54:31:68:3 | { ... } | Test.java:54:26:54:26 | j | +| Test.java:54:31:68:3 | { ... } | Test.java:57:5:57:13 | if (...) | +| Test.java:54:31:68:3 | { ... } | Test.java:57:15:60:5 | { ... } | +| Test.java:54:31:68:3 | { ... } | Test.java:60:12:62:5 | { ... } | +| Test.java:54:31:68:3 | { ... } | Test.java:63:9:66:4 | { ... } | +| Test.java:57:5:57:13 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:57:5:57:13 | if (...) | Test.java:60:12:62:5 | { ... } | diff --git a/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected b/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected index 3aeb7b5553d..85e440eb5b1 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected @@ -1,30 +1,30 @@ -| Test.java:4:21:76:2 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:11:14:14:3 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:14:10:16:3 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:24:4:24:10 | stmt | Test.java:4:14:4:17 | test | -| Test.java:30:15:33:3 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:38:9:38:9 | x | -| Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | stmt | -| Test.java:38:9:38:9 | x | Test.java:43:3:43:9 | stmt | -| Test.java:38:16:41:3 | stmt | Test.java:38:9:38:9 | x | -| Test.java:43:3:43:9 | stmt | Test.java:46:18:46:18 | j | -| Test.java:46:18:46:18 | j | Test.java:46:31:49:3 | stmt | -| Test.java:46:18:46:18 | j | Test.java:51:3:51:9 | stmt | -| Test.java:46:31:49:3 | stmt | Test.java:46:18:46:18 | j | -| Test.java:51:3:51:9 | stmt | Test.java:54:18:54:18 | j | -| Test.java:54:18:54:18 | j | Test.java:54:31:68:3 | stmt | -| Test.java:54:18:54:18 | j | Test.java:70:3:70:9 | stmt | +| Test.java:4:21:76:2 | { ... } | Test.java:11:14:14:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:14:10:16:3 | { ... } | +| Test.java:11:14:14:3 | { ... } | Test.java:18:3:18:8 | ...; | +| Test.java:14:10:16:3 | { ... } | Test.java:18:3:18:8 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:24:4:24:10 | return ... | +| Test.java:22:4:22:10 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:24:4:24:10 | return ... | Test.java:4:14:4:17 | test | +| Test.java:30:15:33:3 | { ... } | Test.java:35:3:35:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:38:9:38:9 | x | +| Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | { ... } | +| Test.java:38:9:38:9 | x | Test.java:43:3:43:9 | ...; | +| Test.java:38:16:41:3 | { ... } | Test.java:38:9:38:9 | x | +| Test.java:43:3:43:9 | ...; | Test.java:46:18:46:18 | j | +| Test.java:46:18:46:18 | j | Test.java:46:31:49:3 | { ... } | +| Test.java:46:18:46:18 | j | Test.java:51:3:51:9 | ...; | +| Test.java:46:31:49:3 | { ... } | Test.java:46:18:46:18 | j | +| Test.java:51:3:51:9 | ...; | Test.java:54:18:54:18 | j | +| Test.java:54:18:54:18 | j | Test.java:54:31:68:3 | { ... } | +| Test.java:54:18:54:18 | j | Test.java:70:3:70:9 | ...; | | Test.java:54:26:54:26 | j | Test.java:54:18:54:18 | j | -| Test.java:54:31:68:3 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:57:15:60:5 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:60:12:62:5 | stmt | Test.java:54:26:54:26 | j | -| Test.java:63:9:66:4 | stmt | Test.java:54:26:54:26 | j | -| Test.java:70:3:70:9 | stmt | Test.java:4:14:4:17 | test | +| Test.java:54:31:68:3 | { ... } | Test.java:57:5:57:13 | if (...) | +| Test.java:54:31:68:3 | { ... } | Test.java:63:9:66:4 | { ... } | +| Test.java:57:5:57:13 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:57:5:57:13 | if (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:57:15:60:5 | { ... } | Test.java:70:3:70:9 | ...; | +| Test.java:60:12:62:5 | { ... } | Test.java:54:26:54:26 | j | +| Test.java:63:9:66:4 | { ... } | Test.java:54:26:54:26 | j | +| Test.java:70:3:70:9 | ...; | Test.java:4:14:4:17 | test | diff --git a/java/ql/test/library-tests/controlflow/basic/strictDominance.expected b/java/ql/test/library-tests/controlflow/basic/strictDominance.expected index 10dedd2727a..6db49af5ad8 100644 --- a/java/ql/test/library-tests/controlflow/basic/strictDominance.expected +++ b/java/ql/test/library-tests/controlflow/basic/strictDominance.expected @@ -1,628 +1,628 @@ -| Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | super(...) | -| Test.java:4:21:76:2 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:4:21:76:2 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:11:14:14:3 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:11:14:14:3 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:12:4:12:10 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:14:10:16:3 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:21:3:21:11 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:24:4:24:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:22:4:22:10 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:30:15:33:3 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:30:15:33:3 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:31:4:31:10 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:38:16:41:3 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:38:16:41:3 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:39:4:39:10 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:46:31:49:3 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:46:31:49:3 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:47:4:47:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:54:31:68:3 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:57:5:57:13 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:57:15:60:5 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:57:15:60:5 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:58:6:58:11 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:60:12:62:5 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:60:12:62:5 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:61:6:61:12 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:63:9:66:4 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:63:9:66:4 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:64:5:64:11 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:74:3:74:9 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:75:3:75:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:75:3:75:9 | stmt | +| Test.java:3:14:3:17 | { ... } | Test.java:3:14:3:17 | super(...) | +| Test.java:4:21:76:2 | { ... } | Test.java:5:3:5:12 | local variable declaration | +| Test.java:4:21:76:2 | { ... } | Test.java:6:3:6:14 | local variable declaration | +| Test.java:4:21:76:2 | { ... } | Test.java:7:3:7:12 | local variable declaration | +| Test.java:4:21:76:2 | { ... } | Test.java:8:3:8:12 | local variable declaration | +| Test.java:4:21:76:2 | { ... } | Test.java:11:3:11:12 | if (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:11:14:14:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:12:4:12:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:13:4:13:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:14:10:16:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:15:4:15:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:18:3:18:8 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:21:3:21:11 | if (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:22:4:22:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:24:4:24:10 | return ... | +| Test.java:4:21:76:2 | { ... } | Test.java:27:3:27:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:30:3:30:13 | if (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:30:15:33:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:31:4:31:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:32:4:32:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:35:3:35:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:38:3:38:14 | while (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:38:16:41:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:39:4:39:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:40:4:40:7 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:43:3:43:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:46:3:46:29 | for (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:46:31:49:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:47:4:47:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:48:4:48:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:51:3:51:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:54:3:54:29 | for (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:54:31:68:3 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:55:4:55:10 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:56:4:56:12 | if (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:57:5:57:13 | if (...) | +| Test.java:4:21:76:2 | { ... } | Test.java:57:15:60:5 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:58:6:58:11 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:59:6:59:11 | break | +| Test.java:4:21:76:2 | { ... } | Test.java:60:12:62:5 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:61:6:61:12 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:63:9:66:4 | { ... } | +| Test.java:4:21:76:2 | { ... } | Test.java:64:5:64:11 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:65:5:65:13 | continue | +| Test.java:4:21:76:2 | { ... } | Test.java:67:4:67:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:70:3:70:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:74:3:74:9 | ...; | +| Test.java:4:21:76:2 | { ... } | Test.java:75:3:75:9 | return ... | +| Test.java:5:3:5:12 | local variable declaration | Test.java:6:3:6:14 | local variable declaration | +| Test.java:5:3:5:12 | local variable declaration | Test.java:7:3:7:12 | local variable declaration | +| Test.java:5:3:5:12 | local variable declaration | Test.java:8:3:8:12 | local variable declaration | +| Test.java:5:3:5:12 | local variable declaration | Test.java:11:3:11:12 | if (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:11:14:14:3 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:12:4:12:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:13:4:13:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:14:10:16:3 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:15:4:15:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:18:3:18:8 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:21:3:21:11 | if (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:22:4:22:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:24:4:24:10 | return ... | +| Test.java:5:3:5:12 | local variable declaration | Test.java:27:3:27:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:30:3:30:13 | if (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:30:15:33:3 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:31:4:31:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:32:4:32:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:35:3:35:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:38:3:38:14 | while (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:38:16:41:3 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:39:4:39:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:40:4:40:7 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:43:3:43:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:46:3:46:29 | for (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:46:31:49:3 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:47:4:47:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:48:4:48:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:51:3:51:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:54:3:54:29 | for (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:54:31:68:3 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:55:4:55:10 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:56:4:56:12 | if (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:57:5:57:13 | if (...) | +| Test.java:5:3:5:12 | local variable declaration | Test.java:57:15:60:5 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:58:6:58:11 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:59:6:59:11 | break | +| Test.java:5:3:5:12 | local variable declaration | Test.java:60:12:62:5 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:61:6:61:12 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:63:9:66:4 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:64:5:64:11 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:65:5:65:13 | continue | +| Test.java:5:3:5:12 | local variable declaration | Test.java:67:4:67:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:70:3:70:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:74:3:74:9 | ...; | +| Test.java:5:3:5:12 | local variable declaration | Test.java:75:3:75:9 | return ... | +| Test.java:6:3:6:14 | local variable declaration | Test.java:7:3:7:12 | local variable declaration | +| Test.java:6:3:6:14 | local variable declaration | Test.java:8:3:8:12 | local variable declaration | +| Test.java:6:3:6:14 | local variable declaration | Test.java:11:3:11:12 | if (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:11:14:14:3 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:12:4:12:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:13:4:13:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:14:10:16:3 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:15:4:15:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:18:3:18:8 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:21:3:21:11 | if (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:22:4:22:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:24:4:24:10 | return ... | +| Test.java:6:3:6:14 | local variable declaration | Test.java:27:3:27:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:30:3:30:13 | if (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:30:15:33:3 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:31:4:31:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:32:4:32:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:35:3:35:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:38:3:38:14 | while (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:38:16:41:3 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:39:4:39:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:40:4:40:7 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:43:3:43:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:46:3:46:29 | for (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:46:31:49:3 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:47:4:47:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:48:4:48:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:51:3:51:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:54:3:54:29 | for (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:54:31:68:3 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:55:4:55:10 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:56:4:56:12 | if (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:57:5:57:13 | if (...) | +| Test.java:6:3:6:14 | local variable declaration | Test.java:57:15:60:5 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:58:6:58:11 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:59:6:59:11 | break | +| Test.java:6:3:6:14 | local variable declaration | Test.java:60:12:62:5 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:61:6:61:12 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:63:9:66:4 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:64:5:64:11 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:65:5:65:13 | continue | +| Test.java:6:3:6:14 | local variable declaration | Test.java:67:4:67:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:70:3:70:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:74:3:74:9 | ...; | +| Test.java:6:3:6:14 | local variable declaration | Test.java:75:3:75:9 | return ... | +| Test.java:7:3:7:12 | local variable declaration | Test.java:8:3:8:12 | local variable declaration | +| Test.java:7:3:7:12 | local variable declaration | Test.java:11:3:11:12 | if (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:11:14:14:3 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:12:4:12:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:13:4:13:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:14:10:16:3 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:15:4:15:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:18:3:18:8 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:21:3:21:11 | if (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:22:4:22:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:24:4:24:10 | return ... | +| Test.java:7:3:7:12 | local variable declaration | Test.java:27:3:27:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:30:3:30:13 | if (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:30:15:33:3 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:31:4:31:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:32:4:32:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:35:3:35:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:38:3:38:14 | while (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:38:16:41:3 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:39:4:39:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:40:4:40:7 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:43:3:43:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:46:3:46:29 | for (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:46:31:49:3 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:47:4:47:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:48:4:48:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:51:3:51:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:54:3:54:29 | for (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:54:31:68:3 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:55:4:55:10 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:56:4:56:12 | if (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:57:5:57:13 | if (...) | +| Test.java:7:3:7:12 | local variable declaration | Test.java:57:15:60:5 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:58:6:58:11 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:59:6:59:11 | break | +| Test.java:7:3:7:12 | local variable declaration | Test.java:60:12:62:5 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:61:6:61:12 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:63:9:66:4 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:64:5:64:11 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:65:5:65:13 | continue | +| Test.java:7:3:7:12 | local variable declaration | Test.java:67:4:67:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:70:3:70:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:74:3:74:9 | ...; | +| Test.java:7:3:7:12 | local variable declaration | Test.java:75:3:75:9 | return ... | +| Test.java:8:3:8:12 | local variable declaration | Test.java:11:3:11:12 | if (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:11:14:14:3 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:12:4:12:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:13:4:13:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:14:10:16:3 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:15:4:15:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:18:3:18:8 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:21:3:21:11 | if (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:22:4:22:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:24:4:24:10 | return ... | +| Test.java:8:3:8:12 | local variable declaration | Test.java:27:3:27:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:30:3:30:13 | if (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:30:15:33:3 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:31:4:31:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:32:4:32:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:35:3:35:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:38:3:38:14 | while (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:38:16:41:3 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:39:4:39:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:40:4:40:7 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:43:3:43:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:46:3:46:29 | for (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:46:31:49:3 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:47:4:47:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:48:4:48:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:51:3:51:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:54:3:54:29 | for (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:54:31:68:3 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:55:4:55:10 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:56:4:56:12 | if (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:57:5:57:13 | if (...) | +| Test.java:8:3:8:12 | local variable declaration | Test.java:57:15:60:5 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:58:6:58:11 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:59:6:59:11 | break | +| Test.java:8:3:8:12 | local variable declaration | Test.java:60:12:62:5 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:61:6:61:12 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:63:9:66:4 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:64:5:64:11 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:65:5:65:13 | continue | +| Test.java:8:3:8:12 | local variable declaration | Test.java:67:4:67:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:70:3:70:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:74:3:74:9 | ...; | +| Test.java:8:3:8:12 | local variable declaration | Test.java:75:3:75:9 | return ... | +| Test.java:11:3:11:12 | if (...) | Test.java:11:14:14:3 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:12:4:12:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:13:4:13:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:14:10:16:3 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:15:4:15:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:18:3:18:8 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:21:3:21:11 | if (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:22:4:22:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:24:4:24:10 | return ... | +| Test.java:11:3:11:12 | if (...) | Test.java:27:3:27:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:30:3:30:13 | if (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:30:15:33:3 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:31:4:31:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:32:4:32:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:35:3:35:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:38:3:38:14 | while (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:38:16:41:3 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:39:4:39:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:40:4:40:7 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:43:3:43:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:46:3:46:29 | for (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:46:31:49:3 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:47:4:47:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:48:4:48:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:51:3:51:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:54:3:54:29 | for (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:55:4:55:10 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:56:4:56:12 | if (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:11:3:11:12 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:58:6:58:11 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:59:6:59:11 | break | +| Test.java:11:3:11:12 | if (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:61:6:61:12 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:64:5:64:11 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:65:5:65:13 | continue | +| Test.java:11:3:11:12 | if (...) | Test.java:67:4:67:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:70:3:70:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:74:3:74:9 | ...; | +| Test.java:11:3:11:12 | if (...) | Test.java:75:3:75:9 | return ... | +| Test.java:11:14:14:3 | { ... } | Test.java:12:4:12:10 | ...; | +| Test.java:11:14:14:3 | { ... } | Test.java:13:4:13:10 | ...; | +| Test.java:12:4:12:10 | ...; | Test.java:13:4:13:10 | ...; | +| Test.java:14:10:16:3 | { ... } | Test.java:15:4:15:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:21:3:21:11 | if (...) | +| Test.java:18:3:18:8 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:24:4:24:10 | return ... | +| Test.java:18:3:18:8 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:18:3:18:8 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:18:3:18:8 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:18:3:18:8 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:18:3:18:8 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:18:3:18:8 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:18:3:18:8 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:59:6:59:11 | break | +| Test.java:18:3:18:8 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:18:3:18:8 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:21:3:21:11 | if (...) | Test.java:22:4:22:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:24:4:24:10 | return ... | +| Test.java:21:3:21:11 | if (...) | Test.java:27:3:27:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:30:3:30:13 | if (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:30:15:33:3 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:31:4:31:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:32:4:32:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:35:3:35:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:38:3:38:14 | while (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:38:16:41:3 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:39:4:39:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:40:4:40:7 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:43:3:43:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:46:3:46:29 | for (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:46:31:49:3 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:47:4:47:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:48:4:48:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:51:3:51:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:54:3:54:29 | for (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:55:4:55:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:56:4:56:12 | if (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:58:6:58:11 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:59:6:59:11 | break | +| Test.java:21:3:21:11 | if (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:61:6:61:12 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:64:5:64:11 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:65:5:65:13 | continue | +| Test.java:21:3:21:11 | if (...) | Test.java:67:4:67:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:70:3:70:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:74:3:74:9 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:75:3:75:9 | return ... | +| Test.java:22:4:22:10 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:22:4:22:10 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:22:4:22:10 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:22:4:22:10 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:22:4:22:10 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:22:4:22:10 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:22:4:22:10 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:59:6:59:11 | break | +| Test.java:22:4:22:10 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:22:4:22:10 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:22:4:22:10 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:22:4:22:10 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:27:3:27:9 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:27:3:27:9 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:27:3:27:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:27:3:27:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:27:3:27:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:27:3:27:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:27:3:27:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:59:6:59:11 | break | +| Test.java:27:3:27:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:27:3:27:9 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:27:3:27:9 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:30:3:30:13 | if (...) | Test.java:30:15:33:3 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:31:4:31:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:32:4:32:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:35:3:35:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:38:3:38:14 | while (...) | +| Test.java:30:3:30:13 | if (...) | Test.java:38:16:41:3 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:39:4:39:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:40:4:40:7 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:43:3:43:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:46:3:46:29 | for (...) | +| Test.java:30:3:30:13 | if (...) | Test.java:46:31:49:3 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:47:4:47:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:48:4:48:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:51:3:51:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:54:3:54:29 | for (...) | +| Test.java:30:3:30:13 | if (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:55:4:55:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:56:4:56:12 | if (...) | +| Test.java:30:3:30:13 | if (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:30:3:30:13 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:58:6:58:11 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:59:6:59:11 | break | +| Test.java:30:3:30:13 | if (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:61:6:61:12 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:30:3:30:13 | if (...) | Test.java:64:5:64:11 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:65:5:65:13 | continue | +| Test.java:30:3:30:13 | if (...) | Test.java:67:4:67:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:70:3:70:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:74:3:74:9 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:75:3:75:9 | return ... | +| Test.java:30:15:33:3 | { ... } | Test.java:31:4:31:10 | ...; | +| Test.java:30:15:33:3 | { ... } | Test.java:32:4:32:10 | ...; | +| Test.java:31:4:31:10 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:35:3:35:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:35:3:35:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:35:3:35:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:35:3:35:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:35:3:35:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:59:6:59:11 | break | +| Test.java:35:3:35:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:35:3:35:9 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:38:3:38:14 | while (...) | Test.java:38:16:41:3 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:39:4:39:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:40:4:40:7 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:43:3:43:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:46:3:46:29 | for (...) | +| Test.java:38:3:38:14 | while (...) | Test.java:46:31:49:3 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:47:4:47:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:48:4:48:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:51:3:51:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:54:3:54:29 | for (...) | +| Test.java:38:3:38:14 | while (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:55:4:55:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:56:4:56:12 | if (...) | +| Test.java:38:3:38:14 | while (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:38:3:38:14 | while (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:58:6:58:11 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:59:6:59:11 | break | +| Test.java:38:3:38:14 | while (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:61:6:61:12 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:64:5:64:11 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:65:5:65:13 | continue | +| Test.java:38:3:38:14 | while (...) | Test.java:67:4:67:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:70:3:70:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:74:3:74:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:75:3:75:9 | return ... | +| Test.java:38:16:41:3 | { ... } | Test.java:39:4:39:10 | ...; | +| Test.java:38:16:41:3 | { ... } | Test.java:40:4:40:7 | ...; | +| Test.java:39:4:39:10 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:43:3:43:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:43:3:43:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:43:3:43:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:43:3:43:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:59:6:59:11 | break | +| Test.java:43:3:43:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:43:3:43:9 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:46:3:46:29 | for (...) | Test.java:46:31:49:3 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:47:4:47:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:48:4:48:10 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:51:3:51:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:54:3:54:29 | for (...) | +| Test.java:46:3:46:29 | for (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:55:4:55:10 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:56:4:56:12 | if (...) | +| Test.java:46:3:46:29 | for (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:46:3:46:29 | for (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:58:6:58:11 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:59:6:59:11 | break | +| Test.java:46:3:46:29 | for (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:61:6:61:12 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:64:5:64:11 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:65:5:65:13 | continue | +| Test.java:46:3:46:29 | for (...) | Test.java:67:4:67:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:70:3:70:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:74:3:74:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:75:3:75:9 | return ... | +| Test.java:46:31:49:3 | { ... } | Test.java:47:4:47:9 | ...; | +| Test.java:46:31:49:3 | { ... } | Test.java:48:4:48:10 | ...; | +| Test.java:47:4:47:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:51:3:51:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:51:3:51:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:51:3:51:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:59:6:59:11 | break | +| Test.java:51:3:51:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:51:3:51:9 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:54:3:54:29 | for (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:55:4:55:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:56:4:56:12 | if (...) | +| Test.java:54:3:54:29 | for (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:54:3:54:29 | for (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:58:6:58:11 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:59:6:59:11 | break | +| Test.java:54:3:54:29 | for (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:61:6:61:12 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:64:5:64:11 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:65:5:65:13 | continue | +| Test.java:54:3:54:29 | for (...) | Test.java:67:4:67:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:70:3:70:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:74:3:74:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:75:3:75:9 | return ... | +| Test.java:54:31:68:3 | { ... } | Test.java:55:4:55:10 | ...; | +| Test.java:54:31:68:3 | { ... } | Test.java:56:4:56:12 | if (...) | +| Test.java:54:31:68:3 | { ... } | Test.java:57:5:57:13 | if (...) | +| Test.java:54:31:68:3 | { ... } | Test.java:57:15:60:5 | { ... } | +| Test.java:54:31:68:3 | { ... } | Test.java:58:6:58:11 | ...; | +| Test.java:54:31:68:3 | { ... } | Test.java:59:6:59:11 | break | +| Test.java:54:31:68:3 | { ... } | Test.java:60:12:62:5 | { ... } | +| Test.java:54:31:68:3 | { ... } | Test.java:61:6:61:12 | ...; | +| Test.java:54:31:68:3 | { ... } | Test.java:63:9:66:4 | { ... } | +| Test.java:54:31:68:3 | { ... } | Test.java:64:5:64:11 | ...; | +| Test.java:54:31:68:3 | { ... } | Test.java:65:5:65:13 | continue | +| Test.java:54:31:68:3 | { ... } | Test.java:67:4:67:9 | ...; | +| Test.java:55:4:55:10 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:55:4:55:10 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:55:4:55:10 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:55:4:55:10 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:55:4:55:10 | ...; | Test.java:59:6:59:11 | break | +| Test.java:55:4:55:10 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:55:4:55:10 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:55:4:55:10 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:55:4:55:10 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:55:4:55:10 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:55:4:55:10 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:56:4:56:12 | if (...) | Test.java:57:5:57:13 | if (...) | +| Test.java:56:4:56:12 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:56:4:56:12 | if (...) | Test.java:58:6:58:11 | ...; | +| Test.java:56:4:56:12 | if (...) | Test.java:59:6:59:11 | break | +| Test.java:56:4:56:12 | if (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:56:4:56:12 | if (...) | Test.java:61:6:61:12 | ...; | +| Test.java:56:4:56:12 | if (...) | Test.java:63:9:66:4 | { ... } | +| Test.java:56:4:56:12 | if (...) | Test.java:64:5:64:11 | ...; | +| Test.java:56:4:56:12 | if (...) | Test.java:65:5:65:13 | continue | +| Test.java:56:4:56:12 | if (...) | Test.java:67:4:67:9 | ...; | +| Test.java:57:5:57:13 | if (...) | Test.java:57:15:60:5 | { ... } | +| Test.java:57:5:57:13 | if (...) | Test.java:58:6:58:11 | ...; | +| Test.java:57:5:57:13 | if (...) | Test.java:59:6:59:11 | break | +| Test.java:57:5:57:13 | if (...) | Test.java:60:12:62:5 | { ... } | +| Test.java:57:5:57:13 | if (...) | Test.java:61:6:61:12 | ...; | +| Test.java:57:5:57:13 | if (...) | Test.java:67:4:67:9 | ...; | +| Test.java:57:15:60:5 | { ... } | Test.java:58:6:58:11 | ...; | +| Test.java:57:15:60:5 | { ... } | Test.java:59:6:59:11 | break | +| Test.java:58:6:58:11 | ...; | Test.java:59:6:59:11 | break | +| Test.java:60:12:62:5 | { ... } | Test.java:61:6:61:12 | ...; | +| Test.java:60:12:62:5 | { ... } | Test.java:67:4:67:9 | ...; | +| Test.java:61:6:61:12 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:63:9:66:4 | { ... } | Test.java:64:5:64:11 | ...; | +| Test.java:63:9:66:4 | { ... } | Test.java:65:5:65:13 | continue | +| Test.java:64:5:64:11 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:70:3:70:9 | ...; | Test.java:74:3:74:9 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:75:3:75:9 | return ... | +| Test.java:74:3:74:9 | ...; | Test.java:75:3:75:9 | return ... | diff --git a/java/ql/test/library-tests/controlflow/basic/strictPostDominance.expected b/java/ql/test/library-tests/controlflow/basic/strictPostDominance.expected index b5a1d80647a..83e141e63a5 100644 --- a/java/ql/test/library-tests/controlflow/basic/strictPostDominance.expected +++ b/java/ql/test/library-tests/controlflow/basic/strictPostDominance.expected @@ -1,232 +1,232 @@ -| Test.java:3:14:3:17 | super(...) | Test.java:3:14:3:17 | stmt | -| Test.java:5:3:5:12 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:6:3:6:14 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:7:3:7:12 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:8:3:8:12 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:11:3:11:12 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:12:4:12:10 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:13:4:13:10 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:13:4:13:10 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:15:4:15:10 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:4:21:76:2 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:5:3:5:12 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:6:3:6:14 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:7:3:7:12 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:8:3:8:12 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:11:3:11:12 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:11:14:14:3 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:12:4:12:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:13:4:13:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:14:10:16:3 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:15:4:15:10 | stmt | -| Test.java:21:3:21:11 | stmt | Test.java:18:3:18:8 | stmt | -| Test.java:27:3:27:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:30:3:30:13 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:31:4:31:10 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:32:4:32:10 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:32:4:32:10 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:35:3:35:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:38:3:38:14 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:39:4:39:10 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:40:4:40:7 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:40:4:40:7 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:43:3:43:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:46:3:46:29 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:47:4:47:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:48:4:48:10 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:48:4:48:10 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:51:3:51:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:54:3:54:29 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:55:4:55:10 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:56:4:56:12 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:58:6:58:11 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:59:6:59:11 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:59:6:59:11 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:61:6:61:12 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:64:5:64:11 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:65:5:65:13 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:65:5:65:13 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:67:4:67:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:67:4:67:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:70:3:70:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:74:3:74:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:22:4:22:10 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:27:3:27:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:30:3:30:13 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:30:15:33:3 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:31:4:31:10 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:32:4:32:10 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:38:3:38:14 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:38:16:41:3 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:39:4:39:10 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:40:4:40:7 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:43:3:43:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:46:3:46:29 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:46:31:49:3 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:47:4:47:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:48:4:48:10 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:51:3:51:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:54:3:54:29 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:54:31:68:3 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:55:4:55:10 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:56:4:56:12 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:57:5:57:13 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:57:15:60:5 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:58:6:58:11 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:59:6:59:11 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:60:12:62:5 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:61:6:61:12 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:63:9:66:4 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:64:5:64:11 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:65:5:65:13 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:67:4:67:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:75:3:75:9 | stmt | Test.java:74:3:74:9 | stmt | +| Test.java:3:14:3:17 | super(...) | Test.java:3:14:3:17 | { ... } | +| Test.java:5:3:5:12 | local variable declaration | Test.java:4:21:76:2 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:4:21:76:2 | { ... } | +| Test.java:6:3:6:14 | local variable declaration | Test.java:5:3:5:12 | local variable declaration | +| Test.java:7:3:7:12 | local variable declaration | Test.java:4:21:76:2 | { ... } | +| Test.java:7:3:7:12 | local variable declaration | Test.java:5:3:5:12 | local variable declaration | +| Test.java:7:3:7:12 | local variable declaration | Test.java:6:3:6:14 | local variable declaration | +| Test.java:8:3:8:12 | local variable declaration | Test.java:4:21:76:2 | { ... } | +| Test.java:8:3:8:12 | local variable declaration | Test.java:5:3:5:12 | local variable declaration | +| Test.java:8:3:8:12 | local variable declaration | Test.java:6:3:6:14 | local variable declaration | +| Test.java:8:3:8:12 | local variable declaration | Test.java:7:3:7:12 | local variable declaration | +| Test.java:11:3:11:12 | if (...) | Test.java:4:21:76:2 | { ... } | +| Test.java:11:3:11:12 | if (...) | Test.java:5:3:5:12 | local variable declaration | +| Test.java:11:3:11:12 | if (...) | Test.java:6:3:6:14 | local variable declaration | +| Test.java:11:3:11:12 | if (...) | Test.java:7:3:7:12 | local variable declaration | +| Test.java:11:3:11:12 | if (...) | Test.java:8:3:8:12 | local variable declaration | +| Test.java:12:4:12:10 | ...; | Test.java:11:14:14:3 | { ... } | +| Test.java:13:4:13:10 | ...; | Test.java:11:14:14:3 | { ... } | +| Test.java:13:4:13:10 | ...; | Test.java:12:4:12:10 | ...; | +| Test.java:15:4:15:10 | ...; | Test.java:14:10:16:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:4:21:76:2 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:5:3:5:12 | local variable declaration | +| Test.java:18:3:18:8 | ...; | Test.java:6:3:6:14 | local variable declaration | +| Test.java:18:3:18:8 | ...; | Test.java:7:3:7:12 | local variable declaration | +| Test.java:18:3:18:8 | ...; | Test.java:8:3:8:12 | local variable declaration | +| Test.java:18:3:18:8 | ...; | Test.java:11:3:11:12 | if (...) | +| Test.java:18:3:18:8 | ...; | Test.java:11:14:14:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:12:4:12:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:13:4:13:10 | ...; | +| Test.java:18:3:18:8 | ...; | Test.java:14:10:16:3 | { ... } | +| Test.java:18:3:18:8 | ...; | Test.java:15:4:15:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:4:21:76:2 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:5:3:5:12 | local variable declaration | +| Test.java:21:3:21:11 | if (...) | Test.java:6:3:6:14 | local variable declaration | +| Test.java:21:3:21:11 | if (...) | Test.java:7:3:7:12 | local variable declaration | +| Test.java:21:3:21:11 | if (...) | Test.java:8:3:8:12 | local variable declaration | +| Test.java:21:3:21:11 | if (...) | Test.java:11:3:11:12 | if (...) | +| Test.java:21:3:21:11 | if (...) | Test.java:11:14:14:3 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:12:4:12:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:13:4:13:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:14:10:16:3 | { ... } | +| Test.java:21:3:21:11 | if (...) | Test.java:15:4:15:10 | ...; | +| Test.java:21:3:21:11 | if (...) | Test.java:18:3:18:8 | ...; | +| Test.java:27:3:27:9 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:22:4:22:10 | ...; | +| Test.java:30:3:30:13 | if (...) | Test.java:27:3:27:9 | ...; | +| Test.java:31:4:31:10 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:32:4:32:10 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:32:4:32:10 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:35:3:35:9 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:35:3:35:9 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:35:3:35:9 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:22:4:22:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:27:3:27:9 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:30:3:30:13 | if (...) | +| Test.java:38:3:38:14 | while (...) | Test.java:30:15:33:3 | { ... } | +| Test.java:38:3:38:14 | while (...) | Test.java:31:4:31:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:32:4:32:10 | ...; | +| Test.java:38:3:38:14 | while (...) | Test.java:35:3:35:9 | ...; | +| Test.java:39:4:39:10 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:40:4:40:7 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:40:4:40:7 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:43:3:43:9 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:43:3:43:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:43:3:43:9 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:43:3:43:9 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:22:4:22:10 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:27:3:27:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:30:3:30:13 | if (...) | +| Test.java:46:3:46:29 | for (...) | Test.java:30:15:33:3 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:31:4:31:10 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:32:4:32:10 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:35:3:35:9 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:38:3:38:14 | while (...) | +| Test.java:46:3:46:29 | for (...) | Test.java:38:16:41:3 | { ... } | +| Test.java:46:3:46:29 | for (...) | Test.java:39:4:39:10 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:40:4:40:7 | ...; | +| Test.java:46:3:46:29 | for (...) | Test.java:43:3:43:9 | ...; | +| Test.java:47:4:47:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:48:4:48:10 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:48:4:48:10 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:51:3:51:9 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:51:3:51:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:51:3:51:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:51:3:51:9 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:51:3:51:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:22:4:22:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:27:3:27:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:30:3:30:13 | if (...) | +| Test.java:54:3:54:29 | for (...) | Test.java:30:15:33:3 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:31:4:31:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:32:4:32:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:35:3:35:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:38:3:38:14 | while (...) | +| Test.java:54:3:54:29 | for (...) | Test.java:38:16:41:3 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:39:4:39:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:40:4:40:7 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:43:3:43:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:46:3:46:29 | for (...) | +| Test.java:54:3:54:29 | for (...) | Test.java:46:31:49:3 | { ... } | +| Test.java:54:3:54:29 | for (...) | Test.java:47:4:47:9 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:48:4:48:10 | ...; | +| Test.java:54:3:54:29 | for (...) | Test.java:51:3:51:9 | ...; | +| Test.java:55:4:55:10 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:56:4:56:12 | if (...) | Test.java:54:31:68:3 | { ... } | +| Test.java:56:4:56:12 | if (...) | Test.java:55:4:55:10 | ...; | +| Test.java:58:6:58:11 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:59:6:59:11 | break | Test.java:57:15:60:5 | { ... } | +| Test.java:59:6:59:11 | break | Test.java:58:6:58:11 | ...; | +| Test.java:61:6:61:12 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:64:5:64:11 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:65:5:65:13 | continue | Test.java:63:9:66:4 | { ... } | +| Test.java:65:5:65:13 | continue | Test.java:64:5:64:11 | ...; | +| Test.java:67:4:67:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:67:4:67:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:70:3:70:9 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:70:3:70:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:70:3:70:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:70:3:70:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:70:3:70:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:70:3:70:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:59:6:59:11 | break | +| Test.java:70:3:70:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:70:3:70:9 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:70:3:70:9 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:70:3:70:9 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:22:4:22:10 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:27:3:27:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:30:3:30:13 | if (...) | +| Test.java:74:3:74:9 | ...; | Test.java:30:15:33:3 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:31:4:31:10 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:32:4:32:10 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:35:3:35:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:38:3:38:14 | while (...) | +| Test.java:74:3:74:9 | ...; | Test.java:38:16:41:3 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:39:4:39:10 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:40:4:40:7 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:43:3:43:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:46:3:46:29 | for (...) | +| Test.java:74:3:74:9 | ...; | Test.java:46:31:49:3 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:47:4:47:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:48:4:48:10 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:51:3:51:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:54:3:54:29 | for (...) | +| Test.java:74:3:74:9 | ...; | Test.java:54:31:68:3 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:55:4:55:10 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:56:4:56:12 | if (...) | +| Test.java:74:3:74:9 | ...; | Test.java:57:5:57:13 | if (...) | +| Test.java:74:3:74:9 | ...; | Test.java:57:15:60:5 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:58:6:58:11 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:59:6:59:11 | break | +| Test.java:74:3:74:9 | ...; | Test.java:60:12:62:5 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:61:6:61:12 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:63:9:66:4 | { ... } | +| Test.java:74:3:74:9 | ...; | Test.java:64:5:64:11 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:65:5:65:13 | continue | +| Test.java:74:3:74:9 | ...; | Test.java:67:4:67:9 | ...; | +| Test.java:74:3:74:9 | ...; | Test.java:70:3:70:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:22:4:22:10 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:27:3:27:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:30:3:30:13 | if (...) | +| Test.java:75:3:75:9 | return ... | Test.java:30:15:33:3 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:31:4:31:10 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:32:4:32:10 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:35:3:35:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:38:3:38:14 | while (...) | +| Test.java:75:3:75:9 | return ... | Test.java:38:16:41:3 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:39:4:39:10 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:40:4:40:7 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:43:3:43:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:46:3:46:29 | for (...) | +| Test.java:75:3:75:9 | return ... | Test.java:46:31:49:3 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:47:4:47:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:48:4:48:10 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:51:3:51:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:54:3:54:29 | for (...) | +| Test.java:75:3:75:9 | return ... | Test.java:54:31:68:3 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:55:4:55:10 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:56:4:56:12 | if (...) | +| Test.java:75:3:75:9 | return ... | Test.java:57:5:57:13 | if (...) | +| Test.java:75:3:75:9 | return ... | Test.java:57:15:60:5 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:58:6:58:11 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:59:6:59:11 | break | +| Test.java:75:3:75:9 | return ... | Test.java:60:12:62:5 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:61:6:61:12 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:63:9:66:4 | { ... } | +| Test.java:75:3:75:9 | return ... | Test.java:64:5:64:11 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:65:5:65:13 | continue | +| Test.java:75:3:75:9 | return ... | Test.java:67:4:67:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:70:3:70:9 | ...; | +| Test.java:75:3:75:9 | return ... | Test.java:74:3:74:9 | ...; | diff --git a/java/ql/test/library-tests/controlflow/dominance/dominator.expected b/java/ql/test/library-tests/controlflow/dominance/dominator.expected index 36d5a3f38db..3fbd1f806f3 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominator.expected +++ b/java/ql/test/library-tests/controlflow/dominance/dominator.expected @@ -1,176 +1,176 @@ -| Test.java:2:32:72:2 | stmt | Test.java:3:3:3:8 | stmt | -| Test.java:3:3:3:8 | stmt | Test.java:3:7:3:7 | j | -| Test.java:3:7:3:7 | j | Test.java:4:3:4:14 | stmt | -| Test.java:4:3:4:14 | stmt | Test.java:4:12:4:13 | 50 | -| Test.java:4:8:4:13 | y | Test.java:7:3:7:12 | stmt | +| Test.java:2:32:72:2 | { ... } | Test.java:3:3:3:8 | local variable declaration | +| Test.java:3:3:3:8 | local variable declaration | Test.java:3:7:3:7 | j | +| Test.java:3:7:3:7 | j | Test.java:4:3:4:14 | local variable declaration | +| Test.java:4:3:4:14 | local variable declaration | Test.java:4:12:4:13 | 50 | +| Test.java:4:8:4:13 | y | Test.java:7:3:7:12 | if (...) | | Test.java:4:12:4:13 | 50 | Test.java:4:8:4:13 | y | -| Test.java:7:3:7:12 | stmt | Test.java:7:7:7:7 | x | +| Test.java:7:3:7:12 | if (...) | Test.java:7:7:7:7 | x | | Test.java:7:7:7:7 | x | Test.java:7:11:7:11 | 0 | -| Test.java:7:7:7:11 | ... > ... | Test.java:7:14:10:3 | stmt | -| Test.java:7:7:7:11 | ... > ... | Test.java:10:10:12:3 | stmt | -| Test.java:7:7:7:11 | ... > ... | Test.java:14:3:14:20 | stmt | +| Test.java:7:7:7:11 | ... > ... | Test.java:7:14:10:3 | { ... } | +| Test.java:7:7:7:11 | ... > ... | Test.java:10:10:12:3 | { ... } | +| Test.java:7:7:7:11 | ... > ... | Test.java:14:3:14:20 | ...; | | Test.java:7:11:7:11 | 0 | Test.java:7:7:7:11 | ... > ... | -| Test.java:7:14:10:3 | stmt | Test.java:8:4:8:10 | stmt | -| Test.java:8:4:8:9 | ...=... | Test.java:9:4:9:10 | stmt | -| Test.java:8:4:8:10 | stmt | Test.java:8:8:8:9 | 20 | +| Test.java:7:14:10:3 | { ... } | Test.java:8:4:8:10 | ...; | +| Test.java:8:4:8:9 | ...=... | Test.java:9:4:9:10 | ...; | +| Test.java:8:4:8:10 | ...; | Test.java:8:8:8:9 | 20 | | Test.java:8:8:8:9 | 20 | Test.java:8:4:8:9 | ...=... | -| Test.java:9:4:9:10 | stmt | Test.java:9:8:9:9 | 10 | +| Test.java:9:4:9:10 | ...; | Test.java:9:8:9:9 | 10 | | Test.java:9:8:9:9 | 10 | Test.java:9:4:9:9 | ...=... | -| Test.java:10:10:12:3 | stmt | Test.java:11:4:11:10 | stmt | -| Test.java:11:4:11:10 | stmt | Test.java:11:8:11:9 | 30 | +| Test.java:10:10:12:3 | { ... } | Test.java:11:4:11:10 | ...; | +| Test.java:11:4:11:10 | ...; | Test.java:11:8:11:9 | 30 | | Test.java:11:8:11:9 | 30 | Test.java:11:4:11:9 | ...=... | -| Test.java:14:3:14:19 | ...=... | Test.java:17:3:17:12 | stmt | -| Test.java:14:3:14:20 | stmt | Test.java:14:14:14:14 | x | +| Test.java:14:3:14:19 | ...=... | Test.java:17:3:17:12 | if (...) | +| Test.java:14:3:14:20 | ...; | Test.java:14:14:14:14 | x | | Test.java:14:7:14:19 | (...)... | Test.java:14:3:14:19 | ...=... | | Test.java:14:14:14:14 | x | Test.java:14:18:14:18 | y | | Test.java:14:14:14:18 | ... + ... | Test.java:14:7:14:19 | (...)... | | Test.java:14:18:14:18 | y | Test.java:14:14:14:18 | ... + ... | -| Test.java:17:3:17:12 | stmt | Test.java:17:7:17:7 | x | +| Test.java:17:3:17:12 | if (...) | Test.java:17:7:17:7 | x | | Test.java:17:7:17:7 | x | Test.java:17:11:17:11 | 0 | | Test.java:17:7:17:11 | ... < ... | Test.java:2:6:2:9 | test | -| Test.java:17:7:17:11 | ... < ... | Test.java:18:4:18:10 | stmt | +| Test.java:17:7:17:11 | ... < ... | Test.java:18:4:18:10 | ...; | | Test.java:17:7:17:11 | ... < ... | Test.java:20:11:20:11 | z | | Test.java:17:11:17:11 | 0 | Test.java:17:7:17:11 | ... < ... | -| Test.java:18:4:18:9 | ...=... | Test.java:23:3:23:9 | stmt | -| Test.java:18:4:18:10 | stmt | Test.java:18:8:18:9 | 40 | +| Test.java:18:4:18:9 | ...=... | Test.java:23:3:23:9 | ...; | +| Test.java:18:4:18:10 | ...; | Test.java:18:8:18:9 | 40 | | Test.java:18:8:18:9 | 40 | Test.java:18:4:18:9 | ...=... | -| Test.java:20:11:20:11 | z | Test.java:20:4:20:12 | stmt | -| Test.java:23:3:23:8 | ...=... | Test.java:26:3:26:13 | stmt | -| Test.java:23:3:23:9 | stmt | Test.java:23:7:23:8 | 10 | +| Test.java:20:11:20:11 | z | Test.java:20:4:20:12 | return ... | +| Test.java:23:3:23:8 | ...=... | Test.java:26:3:26:13 | if (...) | +| Test.java:23:3:23:9 | ...; | Test.java:23:7:23:8 | 10 | | Test.java:23:7:23:8 | 10 | Test.java:23:3:23:8 | ...=... | -| Test.java:26:3:26:13 | stmt | Test.java:26:7:26:7 | x | +| Test.java:26:3:26:13 | if (...) | Test.java:26:7:26:7 | x | | Test.java:26:7:26:7 | x | Test.java:26:12:26:12 | 0 | -| Test.java:26:7:26:12 | ... == ... | Test.java:26:15:29:3 | stmt | -| Test.java:26:7:26:12 | ... == ... | Test.java:31:3:31:9 | stmt | +| Test.java:26:7:26:12 | ... == ... | Test.java:26:15:29:3 | { ... } | +| Test.java:26:7:26:12 | ... == ... | Test.java:31:3:31:9 | ...; | | Test.java:26:12:26:12 | 0 | Test.java:26:7:26:12 | ... == ... | -| Test.java:26:15:29:3 | stmt | Test.java:27:4:27:10 | stmt | -| Test.java:27:4:27:9 | ...=... | Test.java:28:4:28:10 | stmt | -| Test.java:27:4:27:10 | stmt | Test.java:27:8:27:9 | 60 | +| Test.java:26:15:29:3 | { ... } | Test.java:27:4:27:10 | ...; | +| Test.java:27:4:27:9 | ...=... | Test.java:28:4:28:10 | ...; | +| Test.java:27:4:27:10 | ...; | Test.java:27:8:27:9 | 60 | | Test.java:27:8:27:9 | 60 | Test.java:27:4:27:9 | ...=... | -| Test.java:28:4:28:10 | stmt | Test.java:28:8:28:9 | 10 | +| Test.java:28:4:28:10 | ...; | Test.java:28:8:28:9 | 10 | | Test.java:28:8:28:9 | 10 | Test.java:28:4:28:9 | ...=... | | Test.java:31:3:31:3 | z | Test.java:31:8:31:8 | x | -| Test.java:31:3:31:8 | ...+=... | Test.java:34:3:34:15 | stmt | -| Test.java:31:3:31:9 | stmt | Test.java:31:3:31:3 | z | +| Test.java:31:3:31:8 | ...+=... | Test.java:34:3:34:15 | while (...) | +| Test.java:31:3:31:9 | ...; | Test.java:31:3:31:3 | z | | Test.java:31:8:31:8 | x | Test.java:31:3:31:8 | ...+=... | -| Test.java:34:3:34:15 | stmt | Test.java:34:10:34:10 | x | +| Test.java:34:3:34:15 | while (...) | Test.java:34:10:34:10 | x | | Test.java:34:10:34:10 | x | Test.java:34:14:34:14 | 0 | -| Test.java:34:10:34:14 | ... > ... | Test.java:34:17:37:3 | stmt | -| Test.java:34:10:34:14 | ... > ... | Test.java:39:3:39:9 | stmt | +| Test.java:34:10:34:14 | ... > ... | Test.java:34:17:37:3 | { ... } | +| Test.java:34:10:34:14 | ... > ... | Test.java:39:3:39:9 | ...; | | Test.java:34:14:34:14 | 0 | Test.java:34:10:34:14 | ... > ... | -| Test.java:34:17:37:3 | stmt | Test.java:35:4:35:10 | stmt | -| Test.java:35:4:35:9 | ...=... | Test.java:36:4:36:7 | stmt | -| Test.java:35:4:35:10 | stmt | Test.java:35:8:35:9 | 10 | +| Test.java:34:17:37:3 | { ... } | Test.java:35:4:35:10 | ...; | +| Test.java:35:4:35:9 | ...=... | Test.java:36:4:36:7 | ...; | +| Test.java:35:4:35:10 | ...; | Test.java:35:8:35:9 | 10 | | Test.java:35:8:35:9 | 10 | Test.java:35:4:35:9 | ...=... | | Test.java:36:4:36:4 | x | Test.java:36:4:36:6 | ...-- | -| Test.java:36:4:36:7 | stmt | Test.java:36:4:36:4 | x | +| Test.java:36:4:36:7 | ...; | Test.java:36:4:36:4 | x | | Test.java:39:3:39:3 | z | Test.java:39:8:39:8 | y | -| Test.java:39:3:39:8 | ...+=... | Test.java:42:3:42:26 | stmt | -| Test.java:39:3:39:9 | stmt | Test.java:39:3:39:3 | z | +| Test.java:39:3:39:8 | ...+=... | Test.java:42:3:42:26 | for (...) | +| Test.java:39:3:39:9 | ...; | Test.java:39:3:39:3 | z | | Test.java:39:8:39:8 | y | Test.java:39:3:39:8 | ...+=... | -| Test.java:42:3:42:26 | stmt | Test.java:42:12:42:12 | 0 | +| Test.java:42:3:42:26 | for (...) | Test.java:42:12:42:12 | 0 | | Test.java:42:8:42:12 | ...=... | Test.java:42:15:42:15 | j | | Test.java:42:12:42:12 | 0 | Test.java:42:8:42:12 | ...=... | | Test.java:42:15:42:15 | j | Test.java:42:19:42:20 | 10 | -| Test.java:42:15:42:20 | ... < ... | Test.java:42:28:45:3 | stmt | -| Test.java:42:15:42:20 | ... < ... | Test.java:47:3:47:9 | stmt | +| Test.java:42:15:42:20 | ... < ... | Test.java:42:28:45:3 | { ... } | +| Test.java:42:15:42:20 | ... < ... | Test.java:47:3:47:9 | ...; | | Test.java:42:19:42:20 | 10 | Test.java:42:15:42:20 | ... < ... | | Test.java:42:23:42:23 | j | Test.java:42:23:42:25 | ...++ | -| Test.java:42:28:45:3 | stmt | Test.java:43:4:43:9 | stmt | -| Test.java:43:4:43:8 | ...=... | Test.java:44:4:44:10 | stmt | -| Test.java:43:4:43:9 | stmt | Test.java:43:8:43:8 | 0 | +| Test.java:42:28:45:3 | { ... } | Test.java:43:4:43:9 | ...; | +| Test.java:43:4:43:8 | ...=... | Test.java:44:4:44:10 | ...; | +| Test.java:43:4:43:9 | ...; | Test.java:43:8:43:8 | 0 | | Test.java:43:8:43:8 | 0 | Test.java:43:4:43:8 | ...=... | | Test.java:44:4:44:9 | ...=... | Test.java:42:23:42:23 | j | -| Test.java:44:4:44:10 | stmt | Test.java:44:8:44:9 | 10 | +| Test.java:44:4:44:10 | ...; | Test.java:44:8:44:9 | 10 | | Test.java:44:8:44:9 | 10 | Test.java:44:4:44:9 | ...=... | | Test.java:47:3:47:3 | z | Test.java:47:8:47:8 | w | -| Test.java:47:3:47:8 | ...+=... | Test.java:50:3:50:26 | stmt | -| Test.java:47:3:47:9 | stmt | Test.java:47:3:47:3 | z | +| Test.java:47:3:47:8 | ...+=... | Test.java:50:3:50:26 | for (...) | +| Test.java:47:3:47:9 | ...; | Test.java:47:3:47:3 | z | | Test.java:47:8:47:8 | w | Test.java:47:3:47:8 | ...+=... | -| Test.java:50:3:50:26 | stmt | Test.java:50:12:50:12 | 0 | +| Test.java:50:3:50:26 | for (...) | Test.java:50:12:50:12 | 0 | | Test.java:50:8:50:12 | ...=... | Test.java:50:15:50:15 | j | | Test.java:50:12:50:12 | 0 | Test.java:50:8:50:12 | ...=... | | Test.java:50:15:50:15 | j | Test.java:50:19:50:20 | 10 | -| Test.java:50:15:50:20 | ... < ... | Test.java:50:28:64:3 | stmt | -| Test.java:50:15:50:20 | ... < ... | Test.java:66:3:66:17 | stmt | +| Test.java:50:15:50:20 | ... < ... | Test.java:50:28:64:3 | { ... } | +| Test.java:50:15:50:20 | ... < ... | Test.java:66:3:66:17 | ...; | | Test.java:50:19:50:20 | 10 | Test.java:50:15:50:20 | ... < ... | | Test.java:50:23:50:23 | j | Test.java:50:23:50:25 | ...++ | -| Test.java:50:28:64:3 | stmt | Test.java:51:4:51:10 | stmt | -| Test.java:51:4:51:9 | ...=... | Test.java:52:4:52:13 | stmt | -| Test.java:51:4:51:10 | stmt | Test.java:51:8:51:9 | 30 | +| Test.java:50:28:64:3 | { ... } | Test.java:51:4:51:10 | ...; | +| Test.java:51:4:51:9 | ...=... | Test.java:52:4:52:13 | if (...) | +| Test.java:51:4:51:10 | ...; | Test.java:51:8:51:9 | 30 | | Test.java:51:8:51:9 | 30 | Test.java:51:4:51:9 | ...=... | -| Test.java:52:4:52:13 | stmt | Test.java:52:8:52:8 | z | +| Test.java:52:4:52:13 | if (...) | Test.java:52:8:52:8 | z | | Test.java:52:8:52:8 | z | Test.java:52:12:52:12 | 0 | | Test.java:52:8:52:12 | ... > ... | Test.java:50:23:50:23 | j | -| Test.java:52:8:52:12 | ... > ... | Test.java:53:5:53:14 | stmt | -| Test.java:52:8:52:12 | ... > ... | Test.java:59:9:62:4 | stmt | +| Test.java:52:8:52:12 | ... > ... | Test.java:53:5:53:14 | if (...) | +| Test.java:52:8:52:12 | ... > ... | Test.java:59:9:62:4 | { ... } | | Test.java:52:12:52:12 | 0 | Test.java:52:8:52:12 | ... > ... | -| Test.java:53:5:53:14 | stmt | Test.java:53:9:53:9 | y | +| Test.java:53:5:53:14 | if (...) | Test.java:53:9:53:9 | y | | Test.java:53:9:53:9 | y | Test.java:53:13:53:13 | 0 | -| Test.java:53:9:53:13 | ... > ... | Test.java:53:16:56:5 | stmt | -| Test.java:53:9:53:13 | ... > ... | Test.java:56:12:58:5 | stmt | +| Test.java:53:9:53:13 | ... > ... | Test.java:53:16:56:5 | { ... } | +| Test.java:53:9:53:13 | ... > ... | Test.java:56:12:58:5 | { ... } | | Test.java:53:13:53:13 | 0 | Test.java:53:9:53:13 | ... > ... | -| Test.java:53:16:56:5 | stmt | Test.java:54:6:54:11 | stmt | -| Test.java:54:6:54:10 | ...=... | Test.java:55:6:55:11 | stmt | -| Test.java:54:6:54:11 | stmt | Test.java:54:10:54:10 | 0 | +| Test.java:53:16:56:5 | { ... } | Test.java:54:6:54:11 | ...; | +| Test.java:54:6:54:10 | ...=... | Test.java:55:6:55:11 | break | +| Test.java:54:6:54:11 | ...; | Test.java:54:10:54:10 | 0 | | Test.java:54:10:54:10 | 0 | Test.java:54:6:54:10 | ...=... | -| Test.java:56:12:58:5 | stmt | Test.java:57:6:57:12 | stmt | -| Test.java:57:6:57:11 | ...=... | Test.java:63:4:63:9 | stmt | -| Test.java:57:6:57:12 | stmt | Test.java:57:10:57:11 | 20 | +| Test.java:56:12:58:5 | { ... } | Test.java:57:6:57:12 | ...; | +| Test.java:57:6:57:11 | ...=... | Test.java:63:4:63:9 | ...; | +| Test.java:57:6:57:12 | ...; | Test.java:57:10:57:11 | 20 | | Test.java:57:10:57:11 | 20 | Test.java:57:6:57:11 | ...=... | -| Test.java:59:9:62:4 | stmt | Test.java:60:5:60:11 | stmt | -| Test.java:60:5:60:10 | ...=... | Test.java:61:5:61:13 | stmt | -| Test.java:60:5:60:11 | stmt | Test.java:60:9:60:10 | 10 | +| Test.java:59:9:62:4 | { ... } | Test.java:60:5:60:11 | ...; | +| Test.java:60:5:60:10 | ...=... | Test.java:61:5:61:13 | continue | +| Test.java:60:5:60:11 | ...; | Test.java:60:9:60:10 | 10 | | Test.java:60:9:60:10 | 10 | Test.java:60:5:60:10 | ...=... | -| Test.java:63:4:63:9 | stmt | Test.java:63:8:63:8 | 0 | +| Test.java:63:4:63:9 | ...; | Test.java:63:8:63:8 | 0 | | Test.java:63:8:63:8 | 0 | Test.java:63:4:63:8 | ...=... | | Test.java:66:3:66:3 | z | Test.java:66:8:66:8 | x | -| Test.java:66:3:66:16 | ...+=... | Test.java:70:3:70:9 | stmt | -| Test.java:66:3:66:17 | stmt | Test.java:66:3:66:3 | z | +| Test.java:66:3:66:16 | ...+=... | Test.java:70:3:70:9 | ...; | +| Test.java:66:3:66:17 | ...; | Test.java:66:3:66:3 | z | | Test.java:66:8:66:8 | x | Test.java:66:12:66:12 | y | | Test.java:66:8:66:12 | ... + ... | Test.java:66:16:66:16 | w | | Test.java:66:8:66:16 | ... + ... | Test.java:66:3:66:16 | ...+=... | | Test.java:66:12:66:12 | y | Test.java:66:8:66:12 | ... + ... | | Test.java:66:16:66:16 | w | Test.java:66:8:66:16 | ... + ... | | Test.java:70:3:70:8 | ...=... | Test.java:71:10:71:10 | w | -| Test.java:70:3:70:9 | stmt | Test.java:70:7:70:8 | 40 | +| Test.java:70:3:70:9 | ...; | Test.java:70:7:70:8 | 40 | | Test.java:70:7:70:8 | 40 | Test.java:70:3:70:8 | ...=... | -| Test.java:71:10:71:10 | w | Test.java:71:3:71:11 | stmt | -| Test.java:74:19:91:2 | stmt | Test.java:76:3:76:8 | stmt | -| Test.java:76:3:76:8 | stmt | Test.java:76:7:76:7 | b | -| Test.java:76:7:76:7 | b | Test.java:77:3:77:8 | stmt | -| Test.java:77:3:77:8 | stmt | Test.java:77:7:77:7 | c | -| Test.java:77:7:77:7 | c | Test.java:78:3:78:8 | stmt | -| Test.java:78:3:78:7 | ...=... | Test.java:79:3:79:13 | stmt | -| Test.java:78:3:78:8 | stmt | Test.java:78:7:78:7 | 0 | +| Test.java:71:10:71:10 | w | Test.java:71:3:71:11 | return ... | +| Test.java:74:19:91:2 | { ... } | Test.java:76:3:76:8 | local variable declaration | +| Test.java:76:3:76:8 | local variable declaration | Test.java:76:7:76:7 | b | +| Test.java:76:7:76:7 | b | Test.java:77:3:77:8 | local variable declaration | +| Test.java:77:3:77:8 | local variable declaration | Test.java:77:7:77:7 | c | +| Test.java:77:7:77:7 | c | Test.java:78:3:78:8 | ...; | +| Test.java:78:3:78:7 | ...=... | Test.java:79:3:79:13 | while (...) | +| Test.java:78:3:78:8 | ...; | Test.java:78:7:78:7 | 0 | | Test.java:78:7:78:7 | 0 | Test.java:78:3:78:7 | ...=... | -| Test.java:79:3:79:13 | stmt | Test.java:79:9:79:12 | true | -| Test.java:79:9:79:12 | true | Test.java:79:15:89:3 | stmt | -| Test.java:79:15:89:3 | stmt | Test.java:80:4:80:10 | stmt | -| Test.java:80:4:80:9 | ...=... | Test.java:81:4:81:15 | stmt | -| Test.java:80:4:80:10 | stmt | Test.java:80:8:80:9 | 10 | +| Test.java:79:3:79:13 | while (...) | Test.java:79:9:79:12 | true | +| Test.java:79:9:79:12 | true | Test.java:79:15:89:3 | { ... } | +| Test.java:79:15:89:3 | { ... } | Test.java:80:4:80:10 | ...; | +| Test.java:80:4:80:9 | ...=... | Test.java:81:4:81:15 | if (...) | +| Test.java:80:4:80:10 | ...; | Test.java:80:8:80:9 | 10 | | Test.java:80:8:80:9 | 10 | Test.java:80:4:80:9 | ...=... | -| Test.java:81:4:81:15 | stmt | Test.java:81:8:81:8 | a | +| Test.java:81:4:81:15 | if (...) | Test.java:81:8:81:8 | a | | Test.java:81:8:81:8 | a | Test.java:81:12:81:14 | 100 | -| Test.java:81:8:81:14 | ... > ... | Test.java:81:17:84:4 | stmt | -| Test.java:81:8:81:14 | ... > ... | Test.java:85:4:85:15 | stmt | +| Test.java:81:8:81:14 | ... > ... | Test.java:81:17:84:4 | { ... } | +| Test.java:81:8:81:14 | ... > ... | Test.java:85:4:85:15 | if (...) | | Test.java:81:12:81:14 | 100 | Test.java:81:8:81:14 | ... > ... | -| Test.java:81:17:84:4 | stmt | Test.java:82:5:82:11 | stmt | -| Test.java:82:5:82:10 | ...=... | Test.java:83:5:83:10 | stmt | -| Test.java:82:5:82:11 | stmt | Test.java:82:9:82:10 | 10 | +| Test.java:81:17:84:4 | { ... } | Test.java:82:5:82:11 | ...; | +| Test.java:82:5:82:10 | ...=... | Test.java:83:5:83:10 | ...; | +| Test.java:82:5:82:11 | ...; | Test.java:82:9:82:10 | 10 | | Test.java:82:9:82:10 | 10 | Test.java:82:5:82:10 | ...=... | -| Test.java:83:5:83:10 | stmt | Test.java:83:9:83:9 | c | +| Test.java:83:5:83:10 | ...; | Test.java:83:9:83:9 | c | | Test.java:83:9:83:9 | c | Test.java:83:5:83:9 | ...=... | -| Test.java:85:4:85:15 | stmt | Test.java:85:8:85:8 | a | +| Test.java:85:4:85:15 | if (...) | Test.java:85:8:85:8 | a | | Test.java:85:8:85:8 | a | Test.java:85:13:85:14 | 10 | | Test.java:85:8:85:14 | ... == ... | Test.java:74:6:74:10 | test2 | -| Test.java:85:8:85:14 | ... == ... | Test.java:86:5:86:10 | stmt | -| Test.java:85:8:85:14 | ... == ... | Test.java:87:4:87:15 | stmt | +| Test.java:85:8:85:14 | ... == ... | Test.java:86:5:86:10 | break | +| Test.java:85:8:85:14 | ... == ... | Test.java:87:4:87:15 | if (...) | | Test.java:85:13:85:14 | 10 | Test.java:85:8:85:14 | ... == ... | -| Test.java:86:5:86:10 | stmt | Test.java:90:10:90:10 | b | -| Test.java:87:4:87:15 | stmt | Test.java:87:8:87:8 | a | +| Test.java:86:5:86:10 | break | Test.java:90:10:90:10 | b | +| Test.java:87:4:87:15 | if (...) | Test.java:87:8:87:8 | a | | Test.java:87:8:87:8 | a | Test.java:87:13:87:14 | 20 | | Test.java:87:8:87:14 | ... == ... | Test.java:88:12:88:12 | c | | Test.java:87:13:87:14 | 20 | Test.java:87:8:87:14 | ... == ... | -| Test.java:88:12:88:12 | c | Test.java:88:5:88:13 | stmt | -| Test.java:90:10:90:10 | b | Test.java:90:3:90:11 | stmt | +| Test.java:88:12:88:12 | c | Test.java:88:5:88:13 | return ... | +| Test.java:90:10:90:10 | b | Test.java:90:3:90:11 | return ... | diff --git a/java/ql/test/library-tests/dependency/PrintAst.expected b/java/ql/test/library-tests/dependency/PrintAst.expected index e9eeb6f75b4..828b2be3199 100644 --- a/java/ql/test/library-tests/dependency/PrintAst.expected +++ b/java/ql/test/library-tests/dependency/PrintAst.expected @@ -22,8 +22,8 @@ dependency/A.java: # 16| 0: [Parameter] f # 16| 0: [TypeAccess] A # 16| 0: [TypeAccess] F -# 16| 5: [BlockStmt] stmt -# 17| 0: [ReturnStmt] stmt +# 16| 5: [BlockStmt] { ... } +# 17| 0: [ReturnStmt] return ... # 17| 0: [NullLiteral] null # 22| 5: [Class] F # 24| 6: [Class] G @@ -38,8 +38,8 @@ dependency/A.java: #-----| 4: (Parameters) # 27| 0: [Parameter] t # 27| 0: [TypeAccess] T -# 27| 5: [BlockStmt] stmt -# 27| 0: [ReturnStmt] stmt +# 27| 5: [BlockStmt] { ... } +# 27| 0: [ReturnStmt] return ... # 27| 0: [VarAccess] t # 28| 3: [Method] test2 # 28| 3: [TypeAccess] void @@ -48,4 +48,4 @@ dependency/A.java: # 28| 0: [TypeAccess] Collection # 28| 0: [WildcardTypeAccess] ? ... # 28| 0: [TypeAccess] Number -# 28| 5: [BlockStmt] stmt +# 28| 5: [BlockStmt] { ... } diff --git a/java/ql/test/library-tests/generics/PrintAst.expected b/java/ql/test/library-tests/generics/PrintAst.expected index 7c4932a6f50..dc03f48d03e 100644 --- a/java/ql/test/library-tests/generics/PrintAst.expected +++ b/java/ql/test/library-tests/generics/PrintAst.expected @@ -42,7 +42,7 @@ generics/A.java: # 20| -1: [TypeAccess] D # 20| 0: [WildcardTypeAccess] ? ... # 20| 1: [TypeAccess] Double -# 21| 7: [BlockStmt] stmt -# 21| 0: [ExprStmt] stmt +# 21| 7: [BlockStmt] { ... } +# 21| 0: [ExprStmt] ...; # 21| 0: [MethodAccess] asList(...) # 21| -1: [TypeAccess] Arrays diff --git a/java/ql/test/library-tests/guards/guards.expected b/java/ql/test/library-tests/guards/guards.expected index 7d8beb623ed..1b7b7d4273d 100644 --- a/java/ql/test/library-tests/guards/guards.expected +++ b/java/ql/test/library-tests/guards/guards.expected @@ -1,41 +1,41 @@ -| Test.java:5:7:5:11 | ... < ... | false | Test.java:8:3:8:12 | stmt | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:8:3:8:12 | local variable declaration | | Test.java:5:7:5:11 | ... < ... | false | Test.java:9:9:9:9 | x | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:9:17:22:3 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:11:5:11:8 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:12:4:12:14 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:12:16:16:4 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:16:11:16:21 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:16:23:18:4 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:18:11:18:22 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:18:24:20:4 | stmt | -| Test.java:5:7:5:11 | ... < ... | false | Test.java:21:4:21:7 | stmt | -| Test.java:5:7:5:11 | ... < ... | true | Test.java:5:14:7:3 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:9:17:22:3 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:11:5:11:8 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:12:4:12:14 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:12:16:16:4 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:16:11:16:21 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:16:23:18:4 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:18:11:18:22 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:18:24:20:4 | stmt | -| Test.java:9:9:9:14 | ... >= ... | true | Test.java:21:4:21:7 | stmt | -| Test.java:10:8:10:13 | ... >= ... | true | Test.java:11:5:11:8 | stmt | -| Test.java:12:8:12:13 | ... > ... | false | Test.java:16:11:16:21 | stmt | -| Test.java:12:8:12:13 | ... > ... | false | Test.java:16:23:18:4 | stmt | -| Test.java:12:8:12:13 | ... > ... | false | Test.java:18:11:18:22 | stmt | -| Test.java:12:8:12:13 | ... > ... | false | Test.java:18:24:20:4 | stmt | -| Test.java:12:8:12:13 | ... > ... | true | Test.java:12:16:16:4 | stmt | -| Test.java:16:15:16:20 | ... < ... | false | Test.java:18:11:18:22 | stmt | -| Test.java:16:15:16:20 | ... < ... | false | Test.java:18:24:20:4 | stmt | -| Test.java:16:15:16:20 | ... < ... | true | Test.java:16:23:18:4 | stmt | -| Test.java:18:15:18:21 | ... == ... | true | Test.java:18:24:20:4 | stmt | -| Test.java:27:7:27:11 | ... > ... | false | Test.java:31:10:36:3 | stmt | -| Test.java:27:7:27:11 | ... > ... | false | Test.java:34:5:34:8 | stmt | -| Test.java:27:7:27:11 | ... > ... | false | Test.java:35:4:35:10 | stmt | -| Test.java:27:7:27:11 | ... > ... | true | Test.java:27:14:31:3 | stmt | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:9:17:22:3 | { ... } | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:11:5:11:8 | ...; | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:12:4:12:14 | if (...) | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:12:16:16:4 | { ... } | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:16:11:16:21 | if (...) | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:16:23:18:4 | { ... } | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:18:11:18:22 | if (...) | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:18:24:20:4 | { ... } | +| Test.java:5:7:5:11 | ... < ... | false | Test.java:21:4:21:7 | ...; | +| Test.java:5:7:5:11 | ... < ... | true | Test.java:5:14:7:3 | { ... } | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:9:17:22:3 | { ... } | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:11:5:11:8 | ...; | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:12:4:12:14 | if (...) | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:12:16:16:4 | { ... } | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:16:11:16:21 | if (...) | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:16:23:18:4 | { ... } | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:18:11:18:22 | if (...) | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:18:24:20:4 | { ... } | +| Test.java:9:9:9:14 | ... >= ... | true | Test.java:21:4:21:7 | ...; | +| Test.java:10:8:10:13 | ... >= ... | true | Test.java:11:5:11:8 | ...; | +| Test.java:12:8:12:13 | ... > ... | false | Test.java:16:11:16:21 | if (...) | +| Test.java:12:8:12:13 | ... > ... | false | Test.java:16:23:18:4 | { ... } | +| Test.java:12:8:12:13 | ... > ... | false | Test.java:18:11:18:22 | if (...) | +| Test.java:12:8:12:13 | ... > ... | false | Test.java:18:24:20:4 | { ... } | +| Test.java:12:8:12:13 | ... > ... | true | Test.java:12:16:16:4 | { ... } | +| Test.java:16:15:16:20 | ... < ... | false | Test.java:18:11:18:22 | if (...) | +| Test.java:16:15:16:20 | ... < ... | false | Test.java:18:24:20:4 | { ... } | +| Test.java:16:15:16:20 | ... < ... | true | Test.java:16:23:18:4 | { ... } | +| Test.java:18:15:18:21 | ... == ... | true | Test.java:18:24:20:4 | { ... } | +| Test.java:27:7:27:11 | ... > ... | false | Test.java:31:10:36:3 | { ... } | +| Test.java:27:7:27:11 | ... > ... | false | Test.java:34:5:34:8 | ...; | +| Test.java:27:7:27:11 | ... > ... | false | Test.java:35:4:35:10 | ...; | +| Test.java:27:7:27:11 | ... > ... | true | Test.java:27:14:31:3 | { ... } | | Test.java:27:7:27:11 | ... > ... | true | Test.java:29:8:29:28 | w | | Test.java:27:7:27:11 | ... > ... | true | Test.java:29:24:29:24 | 0 | | Test.java:27:7:27:11 | ... > ... | true | Test.java:29:28:29:28 | 1 | | Test.java:29:13:29:19 | ... < ... | false | Test.java:29:28:29:28 | 1 | | Test.java:29:13:29:19 | ... < ... | true | Test.java:29:24:29:24 | 0 | -| Test.java:33:8:33:18 | ... < ... | true | Test.java:34:5:34:8 | stmt | +| Test.java:33:8:33:18 | ... < ... | true | Test.java:34:5:34:8 | ...; | diff --git a/java/ql/test/library-tests/guards/guardslogic.expected b/java/ql/test/library-tests/guards/guardslogic.expected index 5ed4a95c5b7..f92d61148fe 100644 --- a/java/ql/test/library-tests/guards/guardslogic.expected +++ b/java/ql/test/library-tests/guards/guardslogic.expected @@ -1,48 +1,48 @@ -| Logic.java:8:10:10:12 | ...?...:... | false | Logic.java:12:12:13:5 | stmt | -| Logic.java:8:10:10:12 | ...?...:... | true | Logic.java:11:21:12:5 | stmt | +| Logic.java:8:10:10:12 | ...?...:... | false | Logic.java:12:12:13:5 | { ... } | +| Logic.java:8:10:10:12 | ...?...:... | true | Logic.java:11:21:12:5 | { ... } | | Logic.java:8:11:8:14 | g(...) | false | Logic.java:10:9:10:12 | true | | Logic.java:8:11:8:14 | g(...) | true | Logic.java:9:11:9:11 | 2 | -| Logic.java:8:11:8:14 | g(...) | true | Logic.java:12:12:13:5 | stmt | -| Logic.java:9:9:9:12 | g(...) | false | Logic.java:12:12:13:5 | stmt | -| Logic.java:11:9:11:9 | b | false | Logic.java:12:12:13:5 | stmt | -| Logic.java:11:9:11:9 | b | true | Logic.java:11:21:12:5 | stmt | -| Logic.java:11:9:11:18 | ... != ... | false | Logic.java:12:12:13:5 | stmt | -| Logic.java:11:9:11:18 | ... != ... | true | Logic.java:11:21:12:5 | stmt | +| Logic.java:8:11:8:14 | g(...) | true | Logic.java:12:12:13:5 | { ... } | +| Logic.java:9:9:9:12 | g(...) | false | Logic.java:12:12:13:5 | { ... } | +| Logic.java:11:9:11:9 | b | false | Logic.java:12:12:13:5 | { ... } | +| Logic.java:11:9:11:9 | b | true | Logic.java:11:21:12:5 | { ... } | +| Logic.java:11:9:11:18 | ... != ... | false | Logic.java:12:12:13:5 | { ... } | +| Logic.java:11:9:11:18 | ... != ... | true | Logic.java:11:21:12:5 | { ... } | | Logic.java:14:14:14:22 | ... != ... | false | Logic.java:14:37:14:37 | 0 | | Logic.java:14:14:14:22 | ... != ... | true | Logic.java:14:26:14:26 | a | | Logic.java:14:14:14:22 | ... != ... | true | Logic.java:15:29:15:29 | i | -| Logic.java:14:14:14:22 | ... != ... | true | Logic.java:15:34:18:5 | stmt | -| Logic.java:14:14:14:22 | ... != ... | true | Logic.java:17:18:17:23 | stmt | +| Logic.java:14:14:14:22 | ... != ... | true | Logic.java:15:34:18:5 | { ... } | +| Logic.java:14:14:14:22 | ... != ... | true | Logic.java:17:18:17:23 | break | | Logic.java:15:21:15:26 | ... < ... | true | Logic.java:15:29:15:29 | i | -| Logic.java:15:21:15:26 | ... < ... | true | Logic.java:15:34:18:5 | stmt | -| Logic.java:15:21:15:26 | ... < ... | true | Logic.java:17:18:17:23 | stmt | +| Logic.java:15:21:15:26 | ... < ... | true | Logic.java:15:34:18:5 | { ... } | +| Logic.java:15:21:15:26 | ... < ... | true | Logic.java:17:18:17:23 | break | | Logic.java:17:11:17:15 | ... > ... | false | Logic.java:15:29:15:29 | i | -| Logic.java:17:11:17:15 | ... > ... | true | Logic.java:17:18:17:23 | stmt | -| Logic.java:19:9:19:12 | g(...) | false | Logic.java:24:7:24:17 | stmt | -| Logic.java:19:9:19:12 | g(...) | false | Logic.java:26:7:26:14 | stmt | -| Logic.java:19:9:19:12 | g(...) | true | Logic.java:20:7:20:16 | stmt | -| Logic.java:22:7:22:17 | stmt | false | Logic.java:26:7:26:14 | stmt | -| Logic.java:22:7:22:17 | stmt | true | Logic.java:22:7:22:17 | stmt | -| Logic.java:24:7:24:17 | stmt | false | Logic.java:26:7:26:14 | stmt | -| Logic.java:24:7:24:17 | stmt | true | Logic.java:24:7:24:17 | stmt | -| Logic.java:26:7:26:14 | stmt | true | Logic.java:26:7:26:14 | stmt | +| Logic.java:17:11:17:15 | ... > ... | true | Logic.java:17:18:17:23 | break | +| Logic.java:19:9:19:12 | g(...) | false | Logic.java:24:7:24:17 | case ... | +| Logic.java:19:9:19:12 | g(...) | false | Logic.java:26:7:26:14 | default | +| Logic.java:19:9:19:12 | g(...) | true | Logic.java:20:7:20:16 | ...; | +| Logic.java:22:7:22:17 | case ... | false | Logic.java:26:7:26:14 | default | +| Logic.java:22:7:22:17 | case ... | true | Logic.java:22:7:22:17 | case ... | +| Logic.java:24:7:24:17 | case ... | false | Logic.java:26:7:26:14 | default | +| Logic.java:24:7:24:17 | case ... | true | Logic.java:24:7:24:17 | case ... | +| Logic.java:26:7:26:14 | default | true | Logic.java:26:7:26:14 | default | | Logic.java:29:16:29:19 | g(...) | false | Logic.java:29:30:29:30 | s | -| Logic.java:29:16:29:19 | g(...) | false | Logic.java:30:30:31:5 | stmt | +| Logic.java:29:16:29:19 | g(...) | false | Logic.java:30:30:31:5 | { ... } | | Logic.java:29:16:29:19 | g(...) | true | Logic.java:29:23:29:26 | null | -| Logic.java:30:9:30:27 | ...instanceof... | true | Logic.java:30:30:31:5 | stmt | -| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:36:5:36:28 | stmt | -| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:37:5:37:15 | stmt | -| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:37:17:39:5 | stmt | -| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:40:5:40:18 | stmt | -| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:36:5:36:28 | stmt | -| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:37:5:37:15 | stmt | -| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:37:17:39:5 | stmt | -| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:40:5:40:18 | stmt | -| Logic.java:36:5:36:27 | checkFalse(...) | false | Logic.java:37:5:37:15 | stmt | -| Logic.java:36:5:36:27 | checkFalse(...) | false | Logic.java:37:17:39:5 | stmt | -| Logic.java:36:5:36:27 | checkFalse(...) | false | Logic.java:40:5:40:18 | stmt | -| Logic.java:36:16:36:21 | g(...) | false | Logic.java:37:5:37:15 | stmt | -| Logic.java:36:16:36:21 | g(...) | false | Logic.java:37:17:39:5 | stmt | -| Logic.java:36:16:36:21 | g(...) | false | Logic.java:40:5:40:18 | stmt | -| Logic.java:37:9:37:14 | ... > ... | true | Logic.java:37:17:39:5 | stmt | +| Logic.java:30:9:30:27 | ...instanceof... | true | Logic.java:30:30:31:5 | { ... } | +| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:36:5:36:28 | ...; | +| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:37:5:37:15 | if (...) | +| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:37:17:39:5 | { ... } | +| Logic.java:35:5:35:29 | checkTrue(...) | true | Logic.java:40:5:40:18 | local variable declaration | +| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:36:5:36:28 | ...; | +| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:37:5:37:15 | if (...) | +| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:37:17:39:5 | { ... } | +| Logic.java:35:15:35:19 | ... > ... | true | Logic.java:40:5:40:18 | local variable declaration | +| Logic.java:36:5:36:27 | checkFalse(...) | false | Logic.java:37:5:37:15 | if (...) | +| Logic.java:36:5:36:27 | checkFalse(...) | false | Logic.java:37:17:39:5 | { ... } | +| Logic.java:36:5:36:27 | checkFalse(...) | false | Logic.java:40:5:40:18 | local variable declaration | +| Logic.java:36:16:36:21 | g(...) | false | Logic.java:37:5:37:15 | if (...) | +| Logic.java:36:16:36:21 | g(...) | false | Logic.java:37:17:39:5 | { ... } | +| Logic.java:36:16:36:21 | g(...) | false | Logic.java:40:5:40:18 | local variable declaration | +| Logic.java:37:9:37:14 | ... > ... | true | Logic.java:37:17:39:5 | { ... } | | Logic.java:44:10:44:10 | b | false | Logic.java:44:33:44:35 | msg | diff --git a/java/ql/test/library-tests/guards12/PrintAst.expected b/java/ql/test/library-tests/guards12/PrintAst.expected index 5ef51e2fd7e..4b28449b418 100644 --- a/java/ql/test/library-tests/guards12/PrintAst.expected +++ b/java/ql/test/library-tests/guards12/PrintAst.expected @@ -6,18 +6,18 @@ Test.java: #-----| 4: (Parameters) # 2| 0: [Parameter] s # 2| 0: [TypeAccess] String -# 2| 5: [BlockStmt] stmt -# 3| 0: [LocalVariableDeclStmt] stmt +# 2| 5: [BlockStmt] { ... } +# 3| 0: [LocalVariableDeclStmt] local variable declaration # 3| 0: [TypeAccess] int # 3| 1: [LocalVariableDeclExpr] x # 3| 0: [SwitchExpr] switch (...) # 3| -1: [VarAccess] s -# 4| 0: [ConstCase] stmt +# 4| 0: [ConstCase] case ... # 4| -1: [IntegerLiteral] 1 # 4| 0: [StringLiteral] "a" # 4| 1: [StringLiteral] "b" -# 5| 1: [ConstCase] stmt +# 5| 1: [ConstCase] case ... # 5| -1: [IntegerLiteral] 2 # 5| 0: [StringLiteral] "c" -# 6| 2: [DefaultCase] stmt +# 6| 2: [DefaultCase] default # 6| -1: [IntegerLiteral] 3 diff --git a/java/ql/test/library-tests/guards12/guard.expected b/java/ql/test/library-tests/guards12/guard.expected index d578ba1141d..4befc404376 100644 --- a/java/ql/test/library-tests/guards12/guard.expected +++ b/java/ql/test/library-tests/guards12/guard.expected @@ -1 +1 @@ -| Test.java:5:7:5:17 | stmt | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:7:5:17 | stmt | +| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:7:5:17 | case ... | diff --git a/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.expected b/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.expected index 73cdcb4209b..85996112d82 100644 --- a/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.expected +++ b/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.expected @@ -1,4 +1,4 @@ -| MultiCatch.java:15:5:15:37 | stmt | MultiCatch.java:15:11:15:21 | IOException | Exception | -| MultiCatch.java:15:5:15:37 | stmt | MultiCatch.java:15:23:15:34 | SQLException | Exception | -| MultiCatch.java:31:5:31:37 | stmt | MultiCatch.java:31:11:31:21 | IOException | Exception | -| MultiCatch.java:31:5:31:37 | stmt | MultiCatch.java:31:23:31:34 | SQLException | Exception | +| MultiCatch.java:15:5:15:37 | catch (...) | MultiCatch.java:15:11:15:21 | IOException | Exception | +| MultiCatch.java:15:5:15:37 | catch (...) | MultiCatch.java:15:23:15:34 | SQLException | Exception | +| MultiCatch.java:31:5:31:37 | catch (...) | MultiCatch.java:31:11:31:21 | IOException | Exception | +| MultiCatch.java:31:5:31:37 | catch (...) | MultiCatch.java:31:23:31:34 | SQLException | Exception | diff --git a/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected b/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected index 624f3a90f7a..29e14d3c120 100644 --- a/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected +++ b/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected @@ -1,48 +1,48 @@ -| MultiCatch.java:6:14:6:23 | stmt | MultiCatch.java:6:14:6:23 | super(...) | | MultiCatch.java:6:14:6:23 | super(...) | MultiCatch.java:6:14:6:23 | MultiCatch | -| MultiCatch.java:8:2:20:2 | stmt | MultiCatch.java:9:3:19:3 | stmt | -| MultiCatch.java:9:3:19:3 | stmt | MultiCatch.java:10:3:15:3 | stmt | -| MultiCatch.java:10:3:15:3 | stmt | MultiCatch.java:11:4:11:8 | stmt | -| MultiCatch.java:11:4:11:8 | stmt | MultiCatch.java:11:7:11:7 | b | +| MultiCatch.java:6:14:6:23 | { ... } | MultiCatch.java:6:14:6:23 | super(...) | +| MultiCatch.java:8:2:20:2 | { ... } | MultiCatch.java:9:3:19:3 | try ... | +| MultiCatch.java:9:3:19:3 | try ... | MultiCatch.java:10:3:15:3 | { ... } | +| MultiCatch.java:10:3:15:3 | { ... } | MultiCatch.java:11:4:11:8 | if (...) | +| MultiCatch.java:11:4:11:8 | if (...) | MultiCatch.java:11:7:11:7 | b | | MultiCatch.java:11:7:11:7 | b | MultiCatch.java:12:11:12:27 | new IOException(...) | | MultiCatch.java:11:7:11:7 | b | MultiCatch.java:14:11:14:28 | new SQLException(...) | -| MultiCatch.java:12:5:12:28 | stmt | MultiCatch.java:15:5:15:37 | stmt | -| MultiCatch.java:12:11:12:27 | new IOException(...) | MultiCatch.java:12:5:12:28 | stmt | -| MultiCatch.java:14:5:14:29 | stmt | MultiCatch.java:15:5:15:37 | stmt | -| MultiCatch.java:14:11:14:28 | new SQLException(...) | MultiCatch.java:14:5:14:29 | stmt | -| MultiCatch.java:15:5:15:37 | stmt | MultiCatch.java:15:36:15:36 | e | -| MultiCatch.java:15:36:15:36 | e | MultiCatch.java:16:3:19:3 | stmt | -| MultiCatch.java:16:3:19:3 | stmt | MultiCatch.java:17:4:17:23 | stmt | +| MultiCatch.java:12:5:12:28 | throw ... | MultiCatch.java:15:5:15:37 | catch (...) | +| MultiCatch.java:12:11:12:27 | new IOException(...) | MultiCatch.java:12:5:12:28 | throw ... | +| MultiCatch.java:14:5:14:29 | throw ... | MultiCatch.java:15:5:15:37 | catch (...) | +| MultiCatch.java:14:11:14:28 | new SQLException(...) | MultiCatch.java:14:5:14:29 | throw ... | +| MultiCatch.java:15:5:15:37 | catch (...) | MultiCatch.java:15:36:15:36 | e | +| MultiCatch.java:15:36:15:36 | e | MultiCatch.java:16:3:19:3 | { ... } | +| MultiCatch.java:16:3:19:3 | { ... } | MultiCatch.java:17:4:17:23 | ...; | | MultiCatch.java:17:4:17:4 | e | MultiCatch.java:17:4:17:22 | printStackTrace(...) | | MultiCatch.java:17:4:17:22 | printStackTrace(...) | MultiCatch.java:18:10:18:10 | e | -| MultiCatch.java:17:4:17:23 | stmt | MultiCatch.java:17:4:17:4 | e | -| MultiCatch.java:18:4:18:11 | stmt | MultiCatch.java:7:14:7:23 | multiCatch | -| MultiCatch.java:18:10:18:10 | e | MultiCatch.java:18:4:18:11 | stmt | -| MultiCatch.java:23:2:33:2 | stmt | MultiCatch.java:24:3:32:4 | stmt | -| MultiCatch.java:24:3:32:4 | stmt | MultiCatch.java:25:3:31:3 | stmt | -| MultiCatch.java:25:3:31:3 | stmt | MultiCatch.java:26:4:26:8 | stmt | -| MultiCatch.java:26:4:26:8 | stmt | MultiCatch.java:26:7:26:7 | b | +| MultiCatch.java:17:4:17:23 | ...; | MultiCatch.java:17:4:17:4 | e | +| MultiCatch.java:18:4:18:11 | throw ... | MultiCatch.java:7:14:7:23 | multiCatch | +| MultiCatch.java:18:10:18:10 | e | MultiCatch.java:18:4:18:11 | throw ... | +| MultiCatch.java:23:2:33:2 | { ... } | MultiCatch.java:24:3:32:4 | try ... | +| MultiCatch.java:24:3:32:4 | try ... | MultiCatch.java:25:3:31:3 | { ... } | +| MultiCatch.java:25:3:31:3 | { ... } | MultiCatch.java:26:4:26:8 | if (...) | +| MultiCatch.java:26:4:26:8 | if (...) | MultiCatch.java:26:7:26:7 | b | | MultiCatch.java:26:7:26:7 | b | MultiCatch.java:27:11:27:27 | new IOException(...) | -| MultiCatch.java:26:7:26:7 | b | MultiCatch.java:28:9:28:13 | stmt | -| MultiCatch.java:27:5:27:28 | stmt | MultiCatch.java:31:5:31:37 | stmt | -| MultiCatch.java:27:11:27:27 | new IOException(...) | MultiCatch.java:27:5:27:28 | stmt | -| MultiCatch.java:28:9:28:13 | stmt | MultiCatch.java:28:12:28:12 | c | +| MultiCatch.java:26:7:26:7 | b | MultiCatch.java:28:9:28:13 | if (...) | +| MultiCatch.java:27:5:27:28 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) | +| MultiCatch.java:27:11:27:27 | new IOException(...) | MultiCatch.java:27:5:27:28 | throw ... | +| MultiCatch.java:28:9:28:13 | if (...) | MultiCatch.java:28:12:28:12 | c | | MultiCatch.java:28:12:28:12 | c | MultiCatch.java:29:11:29:28 | new SQLException(...) | | MultiCatch.java:28:12:28:12 | c | MultiCatch.java:30:10:30:24 | new Exception(...) | -| MultiCatch.java:29:5:29:29 | stmt | MultiCatch.java:31:5:31:37 | stmt | -| MultiCatch.java:29:11:29:28 | new SQLException(...) | MultiCatch.java:29:5:29:29 | stmt | -| MultiCatch.java:30:4:30:25 | stmt | MultiCatch.java:22:14:22:24 | multiCatch2 | -| MultiCatch.java:30:4:30:25 | stmt | MultiCatch.java:31:5:31:37 | stmt | -| MultiCatch.java:30:10:30:24 | new Exception(...) | MultiCatch.java:30:4:30:25 | stmt | -| MultiCatch.java:31:5:31:37 | stmt | MultiCatch.java:31:36:31:36 | e | -| MultiCatch.java:31:36:31:36 | e | MultiCatch.java:32:3:32:4 | stmt | -| MultiCatch.java:32:3:32:4 | stmt | MultiCatch.java:22:14:22:24 | multiCatch2 | -| MultiCatch.java:36:2:42:2 | stmt | MultiCatch.java:37:3:41:4 | stmt | -| MultiCatch.java:37:3:41:4 | stmt | MultiCatch.java:38:3:40:3 | stmt | -| MultiCatch.java:38:3:40:3 | stmt | MultiCatch.java:39:10:39:26 | new IOException(...) | -| MultiCatch.java:39:4:39:27 | stmt | MultiCatch.java:40:5:40:22 | stmt | -| MultiCatch.java:39:10:39:26 | new IOException(...) | MultiCatch.java:39:4:39:27 | stmt | -| MultiCatch.java:39:10:39:26 | new IOException(...) | MultiCatch.java:40:5:40:22 | stmt | -| MultiCatch.java:40:5:40:22 | stmt | MultiCatch.java:40:21:40:21 | e | -| MultiCatch.java:40:21:40:21 | e | MultiCatch.java:41:3:41:4 | stmt | -| MultiCatch.java:41:3:41:4 | stmt | MultiCatch.java:35:14:35:26 | ordinaryCatch | +| MultiCatch.java:29:5:29:29 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) | +| MultiCatch.java:29:11:29:28 | new SQLException(...) | MultiCatch.java:29:5:29:29 | throw ... | +| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:22:14:22:24 | multiCatch2 | +| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) | +| MultiCatch.java:30:10:30:24 | new Exception(...) | MultiCatch.java:30:4:30:25 | throw ... | +| MultiCatch.java:31:5:31:37 | catch (...) | MultiCatch.java:31:36:31:36 | e | +| MultiCatch.java:31:36:31:36 | e | MultiCatch.java:32:3:32:4 | { ... } | +| MultiCatch.java:32:3:32:4 | { ... } | MultiCatch.java:22:14:22:24 | multiCatch2 | +| MultiCatch.java:36:2:42:2 | { ... } | MultiCatch.java:37:3:41:4 | try ... | +| MultiCatch.java:37:3:41:4 | try ... | MultiCatch.java:38:3:40:3 | { ... } | +| MultiCatch.java:38:3:40:3 | { ... } | MultiCatch.java:39:10:39:26 | new IOException(...) | +| MultiCatch.java:39:4:39:27 | throw ... | MultiCatch.java:40:5:40:22 | catch (...) | +| MultiCatch.java:39:10:39:26 | new IOException(...) | MultiCatch.java:39:4:39:27 | throw ... | +| MultiCatch.java:39:10:39:26 | new IOException(...) | MultiCatch.java:40:5:40:22 | catch (...) | +| MultiCatch.java:40:5:40:22 | catch (...) | MultiCatch.java:40:21:40:21 | e | +| MultiCatch.java:40:21:40:21 | e | MultiCatch.java:41:3:41:4 | { ... } | +| MultiCatch.java:41:3:41:4 | { ... } | MultiCatch.java:35:14:35:26 | ordinaryCatch | diff --git a/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected b/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected index bba3b450e3e..c1ef98d7ef8 100644 --- a/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected +++ b/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected @@ -9,28 +9,28 @@ MultiCatch.java: #-----| 4: (Parameters) # 7| 0: [Parameter] b # 7| 0: [TypeAccess] boolean -# 8| 5: [BlockStmt] stmt -# 9| 0: [TryStmt] stmt -# 10| -1: [BlockStmt] stmt -# 11| 0: [IfStmt] stmt +# 8| 5: [BlockStmt] { ... } +# 9| 0: [TryStmt] try ... +# 10| -1: [BlockStmt] { ... } +# 11| 0: [IfStmt] if (...) # 11| 0: [VarAccess] b -# 12| 1: [ThrowStmt] stmt +# 12| 1: [ThrowStmt] throw ... # 12| 0: [ClassInstanceExpr] new IOException(...) # 12| -3: [TypeAccess] IOException -# 14| 2: [ThrowStmt] stmt +# 14| 2: [ThrowStmt] throw ... # 14| 0: [ClassInstanceExpr] new SQLException(...) # 14| -3: [TypeAccess] SQLException -# 15| 0: [CatchClause] stmt +# 15| 0: [CatchClause] catch (...) #-----| 0: (Single Local Variable Declaration) # 15| 0: [UnionTypeAccess] ...|... # 15| 0: [TypeAccess] IOException # 15| 1: [TypeAccess] SQLException # 15| 1: [LocalVariableDeclExpr] e -# 16| 1: [BlockStmt] stmt -# 17| 0: [ExprStmt] stmt +# 16| 1: [BlockStmt] { ... } +# 17| 0: [ExprStmt] ...; # 17| 0: [MethodAccess] printStackTrace(...) # 17| -1: [VarAccess] e -# 18| 1: [ThrowStmt] stmt +# 18| 1: [ThrowStmt] throw ... # 18| 0: [VarAccess] e # 22| 3: [Method] multiCatch2 # 22| 3: [TypeAccess] void @@ -39,39 +39,39 @@ MultiCatch.java: # 22| 0: [TypeAccess] boolean # 22| 1: [Parameter] c # 22| 0: [TypeAccess] boolean -# 23| 5: [BlockStmt] stmt -# 24| 0: [TryStmt] stmt -# 25| -1: [BlockStmt] stmt -# 26| 0: [IfStmt] stmt +# 23| 5: [BlockStmt] { ... } +# 24| 0: [TryStmt] try ... +# 25| -1: [BlockStmt] { ... } +# 26| 0: [IfStmt] if (...) # 26| 0: [VarAccess] b -# 27| 1: [ThrowStmt] stmt +# 27| 1: [ThrowStmt] throw ... # 27| 0: [ClassInstanceExpr] new IOException(...) # 27| -3: [TypeAccess] IOException -# 28| 2: [IfStmt] stmt +# 28| 2: [IfStmt] if (...) # 28| 0: [VarAccess] c -# 29| 1: [ThrowStmt] stmt +# 29| 1: [ThrowStmt] throw ... # 29| 0: [ClassInstanceExpr] new SQLException(...) # 29| -3: [TypeAccess] SQLException -# 30| 1: [ThrowStmt] stmt +# 30| 1: [ThrowStmt] throw ... # 30| 0: [ClassInstanceExpr] new Exception(...) # 30| -3: [TypeAccess] Exception -# 31| 0: [CatchClause] stmt +# 31| 0: [CatchClause] catch (...) #-----| 0: (Single Local Variable Declaration) # 31| 0: [UnionTypeAccess] ...|... # 31| 0: [TypeAccess] IOException # 31| 1: [TypeAccess] SQLException # 31| 1: [LocalVariableDeclExpr] e -# 32| 1: [BlockStmt] stmt +# 32| 1: [BlockStmt] { ... } # 35| 4: [Method] ordinaryCatch # 35| 3: [TypeAccess] void -# 36| 5: [BlockStmt] stmt -# 37| 0: [TryStmt] stmt -# 38| -1: [BlockStmt] stmt -# 39| 0: [ThrowStmt] stmt +# 36| 5: [BlockStmt] { ... } +# 37| 0: [TryStmt] try ... +# 38| -1: [BlockStmt] { ... } +# 39| 0: [ThrowStmt] throw ... # 39| 0: [ClassInstanceExpr] new IOException(...) # 39| -3: [TypeAccess] IOException -# 40| 0: [CatchClause] stmt +# 40| 0: [CatchClause] catch (...) #-----| 0: (Single Local Variable Declaration) # 40| 0: [TypeAccess] Exception # 40| 1: [LocalVariableDeclExpr] e -# 41| 1: [BlockStmt] stmt +# 41| 1: [BlockStmt] { ... } diff --git a/java/ql/test/library-tests/javadoc/PrintAst.expected b/java/ql/test/library-tests/javadoc/PrintAst.expected index 5543dceaf01..84228fe83b3 100644 --- a/java/ql/test/library-tests/javadoc/PrintAst.expected +++ b/java/ql/test/library-tests/javadoc/PrintAst.expected @@ -10,13 +10,13 @@ javadoc/Test.java: # 5| 0: [JavadocText] A javadoc # 6| 1: [JavadocText] comment # 7| 3: [TypeAccess] void -# 7| 5: [BlockStmt] stmt +# 7| 5: [BlockStmt] { ... } # 11| 3: [Method] g #-----| 0: (Javadoc) # 9| 1: [Javadoc] /** Another javadoc comment */ # 9| 0: [JavadocText] Another javadoc comment # 11| 3: [TypeAccess] void -# 11| 5: [BlockStmt] stmt +# 11| 5: [BlockStmt] { ... } # 14| 4: [FieldDeclaration] int x, ...; # 14| -1: [TypeAccess] int # 15| 5: [FieldDeclaration] int y, ...; @@ -26,4 +26,4 @@ javadoc/Test.java: # 17| 1: [Javadoc] /** @deprecated */ # 17| 0: [JavadocTag] @deprecated # 18| 3: [TypeAccess] void -# 18| 5: [BlockStmt] stmt +# 18| 5: [BlockStmt] { ... } diff --git a/java/ql/test/library-tests/localvars/LocalVarDeclStmtChildren.expected b/java/ql/test/library-tests/localvars/LocalVarDeclStmtChildren.expected index 88d42af095e..79c41ba9e46 100644 --- a/java/ql/test/library-tests/localvars/LocalVarDeclStmtChildren.expected +++ b/java/ql/test/library-tests/localvars/LocalVarDeclStmtChildren.expected @@ -1,11 +1,11 @@ -| localvars/LocalVarTest.java:7:9:7:28 | stmt | 0 | localvars/LocalVarTest.java:7:9:7:11 | int | -| localvars/LocalVarTest.java:7:9:7:28 | stmt | 1 | localvars/LocalVarTest.java:7:13:7:18 | x | -| localvars/LocalVarTest.java:7:9:7:28 | stmt | 2 | localvars/LocalVarTest.java:7:22:7:27 | y | -| localvars/LocalVarTest.java:8:9:8:20 | stmt | 0 | localvars/LocalVarTest.java:8:9:8:11 | int | -| localvars/LocalVarTest.java:8:9:8:20 | stmt | 1 | localvars/LocalVarTest.java:8:13:8:18 | z | -| localvars/LocalVarTest.java:9:9:9:35 | stmt | 0 | localvars/LocalVarTest.java:9:9:9:20 | List | -| localvars/LocalVarTest.java:9:9:9:35 | stmt | 1 | localvars/LocalVarTest.java:9:22:9:23 | l1 | -| localvars/LocalVarTest.java:9:9:9:35 | stmt | 2 | localvars/LocalVarTest.java:9:26:9:34 | l2 | -| localvars/LocalVarTest.java:12:13:12:33 | stmt | 0 | localvars/LocalVarTest.java:12:13:12:18 | Object | -| localvars/LocalVarTest.java:12:13:12:33 | stmt | 1 | localvars/LocalVarTest.java:12:20:12:27 | o | -| localvars/LocalVarTest.java:12:13:12:33 | stmt | 2 | localvars/LocalVarTest.java:12:30:12:30 | p | +| localvars/LocalVarTest.java:7:9:7:28 | local variable declaration | 0 | localvars/LocalVarTest.java:7:9:7:11 | int | +| localvars/LocalVarTest.java:7:9:7:28 | local variable declaration | 1 | localvars/LocalVarTest.java:7:13:7:18 | x | +| localvars/LocalVarTest.java:7:9:7:28 | local variable declaration | 2 | localvars/LocalVarTest.java:7:22:7:27 | y | +| localvars/LocalVarTest.java:8:9:8:20 | local variable declaration | 0 | localvars/LocalVarTest.java:8:9:8:11 | int | +| localvars/LocalVarTest.java:8:9:8:20 | local variable declaration | 1 | localvars/LocalVarTest.java:8:13:8:18 | z | +| localvars/LocalVarTest.java:9:9:9:35 | local variable declaration | 0 | localvars/LocalVarTest.java:9:9:9:20 | List | +| localvars/LocalVarTest.java:9:9:9:35 | local variable declaration | 1 | localvars/LocalVarTest.java:9:22:9:23 | l1 | +| localvars/LocalVarTest.java:9:9:9:35 | local variable declaration | 2 | localvars/LocalVarTest.java:9:26:9:34 | l2 | +| localvars/LocalVarTest.java:12:13:12:33 | local variable declaration | 0 | localvars/LocalVarTest.java:12:13:12:18 | Object | +| localvars/LocalVarTest.java:12:13:12:33 | local variable declaration | 1 | localvars/LocalVarTest.java:12:20:12:27 | o | +| localvars/LocalVarTest.java:12:13:12:33 | local variable declaration | 2 | localvars/LocalVarTest.java:12:30:12:30 | p | diff --git a/java/ql/test/library-tests/localvars/TypeAccesses.expected b/java/ql/test/library-tests/localvars/TypeAccesses.expected index 12070ce34d0..cf3ac2eb017 100644 --- a/java/ql/test/library-tests/localvars/TypeAccesses.expected +++ b/java/ql/test/library-tests/localvars/TypeAccesses.expected @@ -1,13 +1,13 @@ | localvars/LocalVarTest.java:6:9:6:11 | int | localvars/LocalVarTest.java:6:13:6:17 | test1 | -1 | -| localvars/LocalVarTest.java:7:9:7:11 | int | localvars/LocalVarTest.java:7:9:7:28 | stmt | 0 | -| localvars/LocalVarTest.java:8:9:8:11 | int | localvars/LocalVarTest.java:8:9:8:20 | stmt | 0 | -| localvars/LocalVarTest.java:9:9:9:20 | List | localvars/LocalVarTest.java:9:9:9:35 | stmt | 0 | +| localvars/LocalVarTest.java:7:9:7:11 | int | localvars/LocalVarTest.java:7:9:7:28 | local variable declaration | 0 | +| localvars/LocalVarTest.java:8:9:8:11 | int | localvars/LocalVarTest.java:8:9:8:20 | local variable declaration | 0 | +| localvars/LocalVarTest.java:9:9:9:20 | List | localvars/LocalVarTest.java:9:9:9:35 | local variable declaration | 0 | | localvars/LocalVarTest.java:9:14:9:19 | String | localvars/LocalVarTest.java:9:9:9:20 | List | 0 | -| localvars/LocalVarTest.java:12:13:12:18 | Object | localvars/LocalVarTest.java:12:13:12:33 | stmt | 0 | +| localvars/LocalVarTest.java:12:13:12:18 | Object | localvars/LocalVarTest.java:12:13:12:33 | local variable declaration | 0 | | localvars/LocalVarTest.java:17:9:17:12 | void | localvars/LocalVarTest.java:17:14:17:18 | test2 | -1 | | localvars/LocalVarTest.java:17:20:17:31 | List | localvars/LocalVarTest.java:17:20:17:33 | l | -1 | | localvars/LocalVarTest.java:17:25:17:30 | String | localvars/LocalVarTest.java:17:20:17:31 | List | 0 | -| localvars/LocalVarTest.java:18:13:18:15 | int | localvars/LocalVarTest.java:18:9:18:29 | stmt | 0 | -| localvars/LocalVarTest.java:19:13:19:15 | int | localvars/LocalVarTest.java:19:9:19:37 | stmt | 0 | -| localvars/LocalVarTest.java:20:13:20:18 | String | localvars/LocalVarTest.java:20:9:20:25 | stmt | -1 | -| localvars/LocalVarTest.java:22:17:22:32 | RuntimeException | localvars/LocalVarTest.java:22:11:22:35 | stmt | -1 | +| localvars/LocalVarTest.java:18:13:18:15 | int | localvars/LocalVarTest.java:18:9:18:29 | for (...) | 0 | +| localvars/LocalVarTest.java:19:13:19:15 | int | localvars/LocalVarTest.java:19:9:19:37 | for (...) | 0 | +| localvars/LocalVarTest.java:20:13:20:18 | String | localvars/LocalVarTest.java:20:9:20:25 | for (... : ...) | -1 | +| localvars/LocalVarTest.java:22:17:22:32 | RuntimeException | localvars/LocalVarTest.java:22:11:22:35 | catch (...) | -1 | diff --git a/java/ql/test/library-tests/modifiers/PrintAst.expected b/java/ql/test/library-tests/modifiers/PrintAst.expected index 6bf393864a0..1fb34c954aa 100644 --- a/java/ql/test/library-tests/modifiers/PrintAst.expected +++ b/java/ql/test/library-tests/modifiers/PrintAst.expected @@ -23,8 +23,8 @@ Test.java: #-----| 1: (Annotations) # 4| 1: [Annotation] Override # 4| 3: [TypeAccess] String -# 4| 5: [BlockStmt] stmt -# 4| 0: [ReturnStmt] stmt +# 4| 5: [BlockStmt] { ... } +# 4| 0: [ReturnStmt] return ... # 4| 0: [StringLiteral] "red" # 4| -3: [TypeAccess] NonFinalEnum # 5| 4: [FieldDeclaration] NonFinalEnum GREEN, ...; diff --git a/java/ql/test/library-tests/printAst/PrintAst.expected b/java/ql/test/library-tests/printAst/PrintAst.expected index 922acc4011a..b89a04e5ffc 100644 --- a/java/ql/test/library-tests/printAst/PrintAst.expected +++ b/java/ql/test/library-tests/printAst/PrintAst.expected @@ -30,14 +30,14 @@ A.java: # 20| 1: [Annotation] SuppressWarnings # 20| 1: [StringLiteral] "all" # 20| 0: [TypeAccess] String -# 20| 5: [BlockStmt] stmt -# 21| 0: [LocalVariableDeclStmt] stmt +# 20| 5: [BlockStmt] { ... } +# 21| 0: [LocalVariableDeclStmt] local variable declaration # 21| 0: [TypeAccess] int # 21| 1: [LocalVariableDeclExpr] i # 21| 0: [IntegerLiteral] 0 # 21| 2: [LocalVariableDeclExpr] j # 21| 0: [IntegerLiteral] 1 -# 23| 1: [ForStmt] stmt +# 23| 1: [ForStmt] for (...) #-----| 0: (For Initializers) # 23| 1: [AssignExpr] ...=... # 23| 0: [VarAccess] i @@ -48,10 +48,10 @@ A.java: # 23| 1: [LTExpr] ... < ... # 23| 0: [VarAccess] i # 23| 1: [IntegerLiteral] 3 -# 23| 2: [BlockStmt] stmt +# 23| 2: [BlockStmt] { ... } # 23| 3: [PostIncExpr] ...++ # 23| 0: [VarAccess] i -# 25| 2: [ForStmt] stmt +# 25| 2: [ForStmt] for (...) #-----| 0: (For Initializers) # 25| 0: [TypeAccess] int # 25| 1: [LocalVariableDeclExpr] m @@ -61,16 +61,16 @@ A.java: # 25| 1: [LTExpr] ... < ... # 25| 0: [VarAccess] m # 25| 1: [IntegerLiteral] 3 -# 25| 2: [BlockStmt] stmt +# 25| 2: [BlockStmt] { ... } # 25| 3: [PostIncExpr] ...++ # 25| 0: [VarAccess] m -# 27| 3: [ReturnStmt] stmt +# 27| 3: [ReturnStmt] return ... # 27| 0: [IntegerLiteral] 0 # 30| 6: [FieldDeclaration] int counter, ...; # 30| -1: [TypeAccess] int # 30| 0: [IntegerLiteral] 1 -# 32| 7: [BlockStmt] stmt -# 33| 0: [ExprStmt] stmt +# 32| 7: [BlockStmt] { ... } +# 33| 0: [ExprStmt] ...; # 33| 0: [AssignExpr] ...=... # 33| 0: [VarAccess] counter # 33| 1: [MethodAccess] doSomething(...) @@ -84,8 +84,8 @@ A.java: # 40| 2: [Annotation] Ann2 # 40| 1: [IntegerLiteral] 7 # 42| 3: [TypeAccess] String -# 42| 5: [BlockStmt] stmt -# 42| 0: [ReturnStmt] stmt +# 42| 5: [BlockStmt] { ... } +# 42| 0: [ReturnStmt] return ... # 42| 0: [StringLiteral] "c" # 44| 9: [Method] varDecls # 44| 3: [TypeAccess] void @@ -93,35 +93,35 @@ A.java: # 44| 0: [Parameter] things # 44| 0: [ArrayTypeAccess] ...[] # 44| 0: [TypeAccess] Object -# 44| 5: [BlockStmt] stmt -# 45| 0: [TryStmt] stmt -# 45| -1: [BlockStmt] stmt -# 46| 0: [EnhancedForStmt] stmt +# 44| 5: [BlockStmt] { ... } +# 45| 0: [TryStmt] try ... +# 45| -1: [BlockStmt] { ... } +# 46| 0: [EnhancedForStmt] for (... : ...) #-----| 0: (Single Local Variable Declaration) # 46| 0: [TypeAccess] Object # 46| 1: [LocalVariableDeclExpr] thing # 46| 1: [VarAccess] things -# 46| 2: [BlockStmt] stmt -# 47| 0: [IfStmt] stmt +# 46| 2: [BlockStmt] { ... } +# 47| 0: [IfStmt] if (...) # 47| 0: [InstanceOfExpr] ...instanceof... # 47| 0: [VarAccess] thing # 47| 1: [TypeAccess] Integer -# 47| 1: [BlockStmt] stmt -# 48| 0: [ReturnStmt] stmt -# 50| 1: [IfStmt] stmt +# 47| 1: [BlockStmt] { ... } +# 48| 0: [ReturnStmt] return ... +# 50| 1: [IfStmt] if (...) # 50| 0: [InstanceOfExpr] ...instanceof... #-----| 0: (Single Local Variable Declaration) # 50| 0: [TypeAccess] String # 50| 1: [LocalVariableDeclExpr] s # 50| 0: [VarAccess] thing -# 50| 1: [BlockStmt] stmt -# 51| 0: [ThrowStmt] stmt +# 50| 1: [BlockStmt] { ... } +# 51| 0: [ThrowStmt] throw ... # 51| 0: [ClassInstanceExpr] new RuntimeException(...) # 51| -3: [TypeAccess] RuntimeException # 51| 0: [VarAccess] s -# 55| 0: [CatchClause] stmt +# 55| 0: [CatchClause] catch (...) #-----| 0: (Single Local Variable Declaration) # 55| 0: [TypeAccess] RuntimeException # 55| 1: [LocalVariableDeclExpr] rte -# 55| 1: [BlockStmt] stmt -# 56| 0: [ReturnStmt] stmt +# 55| 1: [BlockStmt] { ... } +# 56| 0: [ReturnStmt] return ... diff --git a/java/ql/test/library-tests/reflection/PrintAst.expected b/java/ql/test/library-tests/reflection/PrintAst.expected index ede39cfcde5..76560acf118 100644 --- a/java/ql/test/library-tests/reflection/PrintAst.expected +++ b/java/ql/test/library-tests/reflection/PrintAst.expected @@ -19,8 +19,8 @@ reflection/ReflectiveAccess.java: # 13| 1: [Parameter] annotationClass # 13| 0: [TypeAccess] Class # 13| 0: [TypeAccess] A -# 13| 5: [BlockStmt] stmt -# 14| 0: [ReturnStmt] stmt +# 13| 5: [BlockStmt] { ... } +# 14| 0: [ReturnStmt] return ... # 14| 0: [MethodAccess] getAnnotation(...) # 14| -1: [VarAccess] classContainingAnnotation # 14| 0: [VarAccess] annotationClass @@ -30,18 +30,18 @@ reflection/ReflectiveAccess.java: # 17| 0: [Parameter] args # 17| 0: [ArrayTypeAccess] ...[] # 17| 0: [TypeAccess] String -# 17| 5: [BlockStmt] stmt -# 18| 0: [LocalVariableDeclStmt] stmt +# 17| 5: [BlockStmt] { ... } +# 18| 0: [LocalVariableDeclStmt] local variable declaration # 18| 0: [TypeAccess] Class # 18| 0: [WildcardTypeAccess] ? ... # 18| 1: [LocalVariableDeclExpr] testClass # 18| 0: [MethodAccess] forName(...) # 18| -1: [TypeAccess] Class<> # 18| 0: [StringLiteral] "reflection.ReflectiveAccess$TestClass" -# 20| 1: [ExprStmt] stmt +# 20| 1: [ExprStmt] ...; # 20| 0: [MethodAccess] newInstance(...) # 20| -1: [VarAccess] testClass -# 22| 2: [ExprStmt] stmt +# 22| 2: [ExprStmt] ...; # 22| 0: [MethodAccess] getAnnotation(...) # 22| 0: [TypeLiteral] TestClass.class # 22| 0: [TypeAccess] TestClass diff --git a/java/ql/test/library-tests/ssa/ssaDef.expected b/java/ql/test/library-tests/ssa/ssaDef.expected index f3acbc1c2f9..8c9e9cfec51 100644 --- a/java/ql/test/library-tests/ssa/ssaDef.expected +++ b/java/ql/test/library-tests/ssa/ssaDef.expected @@ -2,14 +2,14 @@ | Fields.java:13:5:13:17 | x | Fields.java:15:5:15:10 | ...=... | SSA def(x) | | Fields.java:13:5:13:17 | x | Fields.java:18:5:18:15 | ...=... | SSA def(x) | | Fields.java:13:5:13:17 | x | Fields.java:20:5:20:10 | ...=... | SSA def(x) | -| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | stmt | SSA init(this.xs) | +| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | { ... } | SSA init(this.xs) | | Fields.java:13:15:13:16 | this.xs | Fields.java:14:5:14:9 | upd(...) | SSA impl upd[nonlocal](this.xs) | | Fields.java:13:15:13:16 | this.xs | Fields.java:17:7:17:11 | upd(...) | SSA impl upd[nonlocal](this.xs) | -| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | stmt | SSA phi(this.xs) | +| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | ...; | SSA phi(this.xs) | | Fields.java:13:15:13:16 | this.xs | Fields.java:19:5:19:19 | ...=... | SSA def(this.xs) | | Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | | Fields.java:24:5:24:28 | f | Fields.java:43:7:43:22 | ...=... | SSA def(f) | -| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | stmt | SSA phi(f) | +| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | ...; | SSA phi(f) | | Fields.java:25:5:25:19 | y | Fields.java:25:11:25:18 | y | SSA def(y) | | Fields.java:25:5:25:19 | y | Fields.java:29:5:29:12 | ...=... | SSA def(y) | | Fields.java:25:5:25:19 | y | Fields.java:33:5:33:12 | ...=... | SSA def(y) | @@ -22,14 +22,14 @@ | Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](f.xs) | | Fields.java:25:15:25:18 | f.xs | Fields.java:39:5:39:21 | ...=... | SSA def(f.xs) | | Fields.java:25:15:25:18 | f.xs | Fields.java:43:7:43:22 | ...=... | SSA impl upd[explicit qualifier](f.xs) | -| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | stmt | SSA phi(f.xs) | +| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | ...; | SSA phi(f.xs) | | Fields.java:26:5:26:17 | z | Fields.java:26:11:26:16 | z | SSA def(z) | | Fields.java:26:5:26:17 | z | Fields.java:30:5:30:10 | ...=... | SSA def(z) | | Fields.java:26:5:26:17 | z | Fields.java:34:5:34:10 | ...=... | SSA def(z) | | Fields.java:26:5:26:17 | z | Fields.java:38:5:38:10 | ...=... | SSA def(z) | | Fields.java:26:5:26:17 | z | Fields.java:41:5:41:10 | ...=... | SSA def(z) | | Fields.java:26:5:26:17 | z | Fields.java:47:5:47:10 | ...=... | SSA def(z) | -| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | stmt | SSA init(this.xs) | +| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | { ... } | SSA init(this.xs) | | Fields.java:26:15:26:16 | this.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](this.xs) | | Fields.java:26:15:26:16 | this.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](this.xs) | | Fields.java:26:15:26:16 | this.xs | Fields.java:36:5:36:19 | ...=... | SSA def(this.xs) | @@ -37,52 +37,52 @@ | Fields.java:27:5:27:19 | w | Fields.java:31:5:31:12 | ...=... | SSA def(w) | | Fields.java:27:5:27:19 | w | Fields.java:35:5:35:12 | ...=... | SSA def(w) | | Fields.java:27:5:27:19 | w | Fields.java:48:5:48:12 | ...=... | SSA def(w) | -| Fields.java:27:15:27:18 | Fields.stat | Fields.java:23:19:49:3 | stmt | SSA init(Fields.stat) | +| Fields.java:27:15:27:18 | Fields.stat | Fields.java:23:19:49:3 | { ... } | SSA init(Fields.stat) | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:24:16:24:27 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](Fields.stat) | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](Fields.stat) | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:43:11:43:22 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) | -| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | stmt | SSA phi(Fields.stat) | +| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | ...; | SSA phi(Fields.stat) | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:45:5:45:16 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) | -| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | stmt | SSA init(next(..).p1) | -| Nested.java:4:26:4:31 | p1 | Nested.java:4:34:10:3 | stmt | SSA init(p1) | -| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | stmt | SSA init(next(..).x1) | +| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).p1) | +| Nested.java:4:26:4:31 | p1 | Nested.java:4:34:10:3 | { ... } | SSA init(p1) | +| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | | Nested.java:5:5:5:15 | x1 | Nested.java:5:9:5:14 | x1 | SSA def(x1) | -| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | stmt | SSA init(getInt(..).obj) | -| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | stmt | SSA init(getInt(..).obj) | +| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | { ... } | SSA init(getInt(..).obj) | +| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | { ... } | SSA init(getInt(..).obj) | | Nested.java:15:5:15:30 | obj | Nested.java:15:12:15:29 | obj | SSA def(obj) | -| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | stmt | SSA init(getInt(..).hash) | +| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).hash) | | Nested.java:16:5:16:35 | hash | Nested.java:16:15:16:34 | hash | SSA def(hash) | -| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | stmt | SSA init(getInt(..).x2) | +| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).x2) | | Nested.java:17:5:17:16 | x2 | Nested.java:17:9:17:15 | x2 | SSA def(x2) | | Nested.java:18:5:23:6 | h2 | Nested.java:18:15:23:5 | h2 | SSA def(h2) | | Nested.java:20:9:20:40 | hnest | Nested.java:20:19:20:39 | hnest | SSA def(hnest) | -| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | stmt | SSA init(getInt(..).obj2) | +| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | { ... } | SSA init(getInt(..).obj2) | | Nested.java:24:5:24:31 | obj2 | Nested.java:24:12:24:30 | obj2 | SSA def(obj2) | | Nested.java:24:5:24:31 | obj2 | Nested.java:26:7:26:25 | ...=... | SSA def(obj2) | | Nested.java:24:5:24:31 | obj2 | Nested.java:28:7:28:25 | ...=... | SSA def(obj2) | -| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | stmt | SSA phi(obj2) | +| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | local variable declaration | SSA phi(obj2) | | Nested.java:30:5:30:37 | hash2 | Nested.java:30:15:30:36 | hash2 | SSA def(hash2) | -| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | stmt | SSA init(p3) | -| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | stmt | SSA init(getInt(..).x3) | -| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | stmt | SSA init(getInt(..).x3) | +| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | { ... } | SSA init(p3) | +| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | { ... } | SSA init(getInt(..).x3) | +| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | { ... } | SSA init(getInt(..).x3) | | Nested.java:34:5:34:11 | x3 | Nested.java:34:9:34:10 | x3 | SSA def(x3) | | Nested.java:34:5:34:11 | x3 | Nested.java:36:7:36:12 | ...=... | SSA def(x3) | | Nested.java:34:5:34:11 | x3 | Nested.java:39:7:39:12 | ...=... | SSA def(x3) | -| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | stmt | SSA init(param) | +| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | { ... } | SSA init(param) | | Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | SSA phi(param) | | Test.java:4:8:4:16 | param | Test.java:21:8:21:14 | ...++ | SSA def(param) | | Test.java:6:3:6:12 | x | Test.java:6:7:6:11 | x | SSA def(x) | | Test.java:6:3:6:12 | x | Test.java:10:4:10:6 | ...++ | SSA def(x) | | Test.java:6:3:6:12 | x | Test.java:11:8:11:10 | ++... | SSA def(x) | -| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | stmt | SSA phi(x) | +| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | ; | SSA phi(x) | | Test.java:6:3:6:12 | x | Test.java:27:19:27:19 | i | SSA phi(x) | | Test.java:6:3:6:12 | x | Test.java:28:4:28:9 | ...+=... | SSA def(x) | | Test.java:7:3:7:8 | y | Test.java:7:7:7:7 | y | SSA def(y) | | Test.java:7:3:7:8 | y | Test.java:11:4:11:10 | ...=... | SSA def(y) | | Test.java:7:3:7:8 | y | Test.java:14:4:14:8 | ...=... | SSA def(y) | | Test.java:7:3:7:8 | y | Test.java:15:4:15:9 | ...+=... | SSA def(y) | -| Test.java:7:3:7:8 | y | Test.java:19:3:19:3 | stmt | SSA phi(y) | +| Test.java:7:3:7:8 | y | Test.java:19:3:19:3 | ; | SSA phi(y) | | Test.java:7:3:7:8 | y | Test.java:20:10:20:10 | x | SSA phi(y) | | Test.java:7:3:7:8 | y | Test.java:24:4:24:9 | ...-=... | SSA def(y) | | Test.java:8:3:8:8 | z | Test.java:8:7:8:7 | z | SSA def(z) | @@ -91,15 +91,15 @@ | Test.java:27:8:27:16 | i | Test.java:27:12:27:16 | i | SSA def(i) | | Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | | Test.java:27:8:27:16 | i | Test.java:27:25:27:27 | ...++ | SSA def(i) | -| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | stmt | SSA init(obj) | +| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | { ... } | SSA init(obj) | | TestInstanceOfPattern.java:4:22:4:29 | s | TestInstanceOfPattern.java:4:29:4:29 | s | SSA def(s) | | TestInstanceOfPattern.java:7:8:7:8 | this.s | TestInstanceOfPattern.java:7:8:7:8 | s | SSA impl upd[untracked](this.s) | -| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | stmt | SSA init(obj) | +| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | { ... } | SSA init(obj) | | TestInstanceOfPattern.java:11:24:11:31 | s | TestInstanceOfPattern.java:11:31:11:31 | s | SSA def(s) | | TestInstanceOfPattern.java:12:8:12:8 | this.s | TestInstanceOfPattern.java:12:8:12:8 | s | SSA impl upd[untracked](this.s) | -| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | stmt | SSA init(obj) | +| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | { ... } | SSA init(obj) | | TestInstanceOfPattern.java:18:22:18:29 | s | TestInstanceOfPattern.java:18:29:18:29 | s | SSA def(s) | | TestInstanceOfPattern.java:21:8:21:8 | this.s | TestInstanceOfPattern.java:21:8:21:8 | s | SSA impl upd[untracked](this.s) | -| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | stmt | SSA init(obj) | +| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(obj) | | TestInstanceOfPattern.java:25:22:25:29 | s | TestInstanceOfPattern.java:25:29:25:29 | s | SSA def(s) | -| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | stmt | SSA init(this.s) | +| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | diff --git a/java/ql/test/library-tests/ssa/ssaPhi.expected b/java/ql/test/library-tests/ssa/ssaPhi.expected index db7e81d98e1..fd9f2902f2e 100644 --- a/java/ql/test/library-tests/ssa/ssaPhi.expected +++ b/java/ql/test/library-tests/ssa/ssaPhi.expected @@ -1,22 +1,22 @@ -| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | stmt | Fields.java:14:5:14:9 | upd(...) | -| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | stmt | Fields.java:17:7:17:11 | upd(...) | -| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | stmt | Fields.java:24:12:24:27 | f | -| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | stmt | Fields.java:43:7:43:22 | ...=... | -| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | stmt | Fields.java:39:5:39:21 | ...=... | -| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | stmt | Fields.java:43:7:43:22 | ...=... | -| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | stmt | Fields.java:32:5:32:9 | f(...) | -| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | stmt | Fields.java:43:11:43:22 | new Fields(...) | -| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | stmt | Nested.java:26:7:26:25 | ...=... | -| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | stmt | Nested.java:28:7:28:25 | ...=... | -| Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | Test.java:4:19:32:2 | stmt | +| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | ...; | Fields.java:14:5:14:9 | upd(...) | +| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | ...; | Fields.java:17:7:17:11 | upd(...) | +| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | ...; | Fields.java:24:12:24:27 | f | +| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | ...; | Fields.java:43:7:43:22 | ...=... | +| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | ...; | Fields.java:39:5:39:21 | ...=... | +| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | ...; | Fields.java:43:7:43:22 | ...=... | +| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | ...; | Fields.java:32:5:32:9 | f(...) | +| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | ...; | Fields.java:43:11:43:22 | new Fields(...) | +| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | local variable declaration | Nested.java:26:7:26:25 | ...=... | +| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | local variable declaration | Nested.java:28:7:28:25 | ...=... | +| Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | Test.java:4:19:32:2 | { ... } | | Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | Test.java:21:8:21:14 | ...++ | -| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | stmt | Test.java:6:7:6:11 | x | -| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | stmt | Test.java:11:8:11:10 | ++... | -| Test.java:6:3:6:12 | x | Test.java:27:19:27:19 | i | Test.java:19:3:19:3 | stmt | +| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | ; | Test.java:6:7:6:11 | x | +| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | ; | Test.java:11:8:11:10 | ++... | +| Test.java:6:3:6:12 | x | Test.java:27:19:27:19 | i | Test.java:19:3:19:3 | ; | | Test.java:6:3:6:12 | x | Test.java:27:19:27:19 | i | Test.java:28:4:28:9 | ...+=... | -| Test.java:7:3:7:8 | y | Test.java:19:3:19:3 | stmt | Test.java:11:4:11:10 | ...=... | -| Test.java:7:3:7:8 | y | Test.java:19:3:19:3 | stmt | Test.java:15:4:15:9 | ...+=... | -| Test.java:7:3:7:8 | y | Test.java:20:10:20:10 | x | Test.java:19:3:19:3 | stmt | +| Test.java:7:3:7:8 | y | Test.java:19:3:19:3 | ; | Test.java:11:4:11:10 | ...=... | +| Test.java:7:3:7:8 | y | Test.java:19:3:19:3 | ; | Test.java:15:4:15:9 | ...+=... | +| Test.java:7:3:7:8 | y | Test.java:20:10:20:10 | x | Test.java:19:3:19:3 | ; | | Test.java:7:3:7:8 | y | Test.java:20:10:20:10 | x | Test.java:24:4:24:9 | ...-=... | | Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | Test.java:27:12:27:16 | i | | Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | Test.java:27:25:27:27 | ...++ | diff --git a/java/ql/test/library-tests/ssa/ssaUse.expected b/java/ql/test/library-tests/ssa/ssaUse.expected index b06f5eaf649..f500ebbaa9c 100644 --- a/java/ql/test/library-tests/ssa/ssaUse.expected +++ b/java/ql/test/library-tests/ssa/ssaUse.expected @@ -1,7 +1,7 @@ | Fields.java:13:5:13:17 | x | Fields.java:15:5:15:10 | ...=... | SSA def(x) | Fields.java:16:9:16:9 | x | -| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | stmt | SSA init(this.xs) | Fields.java:13:15:13:16 | xs | +| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | { ... } | SSA init(this.xs) | Fields.java:13:15:13:16 | xs | | Fields.java:13:15:13:16 | this.xs | Fields.java:14:5:14:9 | upd(...) | SSA impl upd[nonlocal](this.xs) | Fields.java:15:9:15:10 | xs | -| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | stmt | SSA phi(this.xs) | Fields.java:18:9:18:15 | this.xs | +| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | ...; | SSA phi(this.xs) | Fields.java:18:9:18:15 | this.xs | | Fields.java:13:15:13:16 | this.xs | Fields.java:19:5:19:19 | ...=... | SSA def(this.xs) | Fields.java:20:9:20:10 | xs | | Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:25:15:25:15 | f | | Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:29:9:29:9 | f | @@ -10,17 +10,17 @@ | Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:37:9:37:9 | f | | Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:39:5:39:5 | f | | Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:40:9:40:9 | f | -| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | stmt | SSA phi(f) | Fields.java:44:9:44:9 | f | -| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | stmt | SSA phi(f) | Fields.java:46:9:46:9 | f | +| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | ...; | SSA phi(f) | Fields.java:44:9:44:9 | f | +| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | ...; | SSA phi(f) | Fields.java:46:9:46:9 | f | | Fields.java:25:15:25:18 | f.xs | Fields.java:24:12:24:27 | f | SSA impl upd[explicit qualifier](f.xs) | Fields.java:25:15:25:18 | f.xs | | Fields.java:25:15:25:18 | f.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](f.xs) | Fields.java:29:9:29:12 | f.xs | | Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](f.xs) | Fields.java:33:9:33:12 | f.xs | | Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](f.xs) | Fields.java:37:9:37:12 | f.xs | | Fields.java:25:15:25:18 | f.xs | Fields.java:39:5:39:21 | ...=... | SSA def(f.xs) | Fields.java:40:9:40:12 | f.xs | -| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | stmt | SSA phi(f.xs) | Fields.java:44:9:44:12 | f.xs | -| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | stmt | SSA phi(f.xs) | Fields.java:46:9:46:12 | f.xs | +| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | ...; | SSA phi(f.xs) | Fields.java:44:9:44:12 | f.xs | +| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | ...; | SSA phi(f.xs) | Fields.java:46:9:46:12 | f.xs | | Fields.java:26:5:26:17 | z | Fields.java:41:5:41:10 | ...=... | SSA def(z) | Fields.java:42:9:42:9 | z | -| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | stmt | SSA init(this.xs) | Fields.java:26:15:26:16 | xs | +| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | { ... } | SSA init(this.xs) | Fields.java:26:15:26:16 | xs | | Fields.java:26:15:26:16 | this.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](this.xs) | Fields.java:30:9:30:10 | xs | | Fields.java:26:15:26:16 | this.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](this.xs) | Fields.java:34:9:34:10 | xs | | Fields.java:26:15:26:16 | this.xs | Fields.java:36:5:36:19 | ...=... | SSA def(this.xs) | Fields.java:38:9:38:10 | xs | @@ -30,25 +30,25 @@ | Fields.java:27:15:27:18 | Fields.stat | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:31:9:31:12 | stat | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:35:9:35:12 | stat | | Fields.java:27:15:27:18 | Fields.stat | Fields.java:45:5:45:16 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:48:9:48:12 | stat | -| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | stmt | SSA init(next(..).p1) | Nested.java:8:38:8:39 | p1 | -| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | stmt | SSA init(next(..).x1) | Nested.java:8:43:8:44 | x1 | -| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | stmt | SSA init(next(..).x1) | Nested.java:8:48:8:49 | x1 | -| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | stmt | SSA init(next(..).x1) | Nested.java:8:53:8:54 | x1 | -| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | stmt | SSA init(getInt(..).obj) | Nested.java:16:22:16:24 | obj | -| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | stmt | SSA init(getInt(..).obj) | Nested.java:20:27:20:29 | obj | -| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | stmt | SSA init(getInt(..).hash) | Nested.java:21:21:21:24 | hash | -| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | stmt | SSA init(getInt(..).x2) | Nested.java:21:16:21:17 | x2 | +| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).p1) | Nested.java:8:38:8:39 | p1 | +| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | Nested.java:8:43:8:44 | x1 | +| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | Nested.java:8:48:8:49 | x1 | +| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | Nested.java:8:53:8:54 | x1 | +| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | { ... } | SSA init(getInt(..).obj) | Nested.java:16:22:16:24 | obj | +| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | { ... } | SSA init(getInt(..).obj) | Nested.java:20:27:20:29 | obj | +| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).hash) | Nested.java:21:21:21:24 | hash | +| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).x2) | Nested.java:21:16:21:17 | x2 | | Nested.java:18:5:23:6 | h2 | Nested.java:18:15:23:5 | h2 | SSA def(h2) | Nested.java:25:9:25:10 | h2 | | Nested.java:20:9:20:40 | hnest | Nested.java:20:19:20:39 | hnest | SSA def(hnest) | Nested.java:21:37:21:41 | hnest | -| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | stmt | SSA init(getInt(..).obj2) | Nested.java:30:23:30:26 | obj2 | -| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | stmt | SSA init(p3) | Nested.java:35:9:35:10 | p3 | -| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | stmt | SSA init(getInt(..).x3) | Nested.java:37:20:37:21 | x3 | -| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | stmt | SSA init(getInt(..).x3) | Nested.java:40:20:40:21 | x3 | -| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | stmt | SSA init(param) | Test.java:9:7:9:11 | param | +| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | { ... } | SSA init(getInt(..).obj2) | Nested.java:30:23:30:26 | obj2 | +| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | { ... } | SSA init(p3) | Nested.java:35:9:35:10 | p3 | +| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | { ... } | SSA init(getInt(..).x3) | Nested.java:37:20:37:21 | x3 | +| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | { ... } | SSA init(getInt(..).x3) | Nested.java:40:20:40:21 | x3 | +| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | { ... } | SSA init(param) | Test.java:9:7:9:11 | param | | Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | SSA phi(param) | Test.java:21:8:21:12 | param | | Test.java:6:3:6:12 | x | Test.java:6:7:6:11 | x | SSA def(x) | Test.java:10:4:10:4 | x | | Test.java:6:3:6:12 | x | Test.java:10:4:10:6 | ...++ | SSA def(x) | Test.java:11:10:11:10 | x | -| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | stmt | SSA phi(x) | Test.java:20:10:20:10 | x | +| Test.java:6:3:6:12 | x | Test.java:19:3:19:3 | ; | SSA phi(x) | Test.java:20:10:20:10 | x | | Test.java:6:3:6:12 | x | Test.java:27:19:27:19 | i | SSA phi(x) | Test.java:28:4:28:4 | x | | Test.java:6:3:6:12 | x | Test.java:27:19:27:19 | i | SSA phi(x) | Test.java:31:10:31:10 | x | | Test.java:7:3:7:8 | y | Test.java:14:4:14:8 | ...=... | SSA def(y) | Test.java:15:4:15:4 | y | @@ -58,17 +58,17 @@ | Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | Test.java:27:19:27:19 | i | | Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | Test.java:27:25:27:25 | i | | Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | Test.java:28:9:28:9 | i | -| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | stmt | SSA init(obj) | TestInstanceOfPattern.java:4:7:4:9 | obj | +| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:4:7:4:9 | obj | | TestInstanceOfPattern.java:4:22:4:29 | s | TestInstanceOfPattern.java:4:29:4:29 | s | SSA def(s) | TestInstanceOfPattern.java:5:8:5:8 | s | | TestInstanceOfPattern.java:7:8:7:8 | this.s | TestInstanceOfPattern.java:7:8:7:8 | s | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:7:8:7:8 | s | -| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | stmt | SSA init(obj) | TestInstanceOfPattern.java:11:9:11:11 | obj | +| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:11:9:11:11 | obj | | TestInstanceOfPattern.java:11:24:11:31 | s | TestInstanceOfPattern.java:11:31:11:31 | s | SSA def(s) | TestInstanceOfPattern.java:14:8:14:8 | s | | TestInstanceOfPattern.java:12:8:12:8 | this.s | TestInstanceOfPattern.java:12:8:12:8 | s | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:12:8:12:8 | s | -| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | stmt | SSA init(obj) | TestInstanceOfPattern.java:18:7:18:9 | obj | +| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:18:7:18:9 | obj | | TestInstanceOfPattern.java:18:22:18:29 | s | TestInstanceOfPattern.java:18:29:18:29 | s | SSA def(s) | TestInstanceOfPattern.java:18:34:18:34 | s | | TestInstanceOfPattern.java:18:22:18:29 | s | TestInstanceOfPattern.java:18:29:18:29 | s | SSA def(s) | TestInstanceOfPattern.java:19:8:19:8 | s | | TestInstanceOfPattern.java:21:8:21:8 | this.s | TestInstanceOfPattern.java:21:8:21:8 | s | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:21:8:21:8 | s | -| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | stmt | SSA init(obj) | TestInstanceOfPattern.java:25:7:25:9 | obj | -| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | stmt | SSA init(this.s) | TestInstanceOfPattern.java:25:34:25:34 | s | -| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | stmt | SSA init(this.s) | TestInstanceOfPattern.java:26:8:26:8 | s | -| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | stmt | SSA init(this.s) | TestInstanceOfPattern.java:28:8:28:8 | s | +| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:25:7:25:9 | obj | +| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | TestInstanceOfPattern.java:25:34:25:34 | s | +| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | TestInstanceOfPattern.java:26:8:26:8 | s | +| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | TestInstanceOfPattern.java:28:8:28:8 | s | diff --git a/java/ql/test/library-tests/stmts/JumpTargets.expected b/java/ql/test/library-tests/stmts/JumpTargets.expected index 1718522d99c..c05796398e3 100644 --- a/java/ql/test/library-tests/stmts/JumpTargets.expected +++ b/java/ql/test/library-tests/stmts/JumpTargets.expected @@ -1,9 +1,9 @@ -| stmts/B.java:8:5:8:10 | stmt | stmts/B.java:6:3:6:26 | stmt | -| stmts/B.java:10:5:10:13 | stmt | stmts/B.java:6:3:6:26 | stmt | -| stmts/B.java:13:6:13:11 | stmt | stmts/B.java:11:4:11:17 | stmt | -| stmts/B.java:15:6:15:17 | stmt | stmts/B.java:6:3:6:26 | stmt | -| stmts/B.java:17:6:17:14 | stmt | stmts/B.java:11:4:11:17 | stmt | -| stmts/B.java:19:6:19:20 | stmt | stmts/B.java:6:3:6:26 | stmt | -| stmts/B.java:22:6:22:11 | stmt | stmts/B.java:20:5:20:14 | stmt | -| stmts/B.java:24:6:24:17 | stmt | stmts/B.java:6:3:6:26 | stmt | -| stmts/B.java:26:6:26:14 | stmt | stmts/B.java:11:4:11:17 | stmt | \ No newline at end of file +| stmts/B.java:8:5:8:10 | break | stmts/B.java:6:3:6:26 | for (...) | +| stmts/B.java:10:5:10:13 | continue | stmts/B.java:6:3:6:26 | for (...) | +| stmts/B.java:13:6:13:11 | break | stmts/B.java:11:4:11:17 | while (...) | +| stmts/B.java:15:6:15:17 | break | stmts/B.java:6:3:6:26 | for (...) | +| stmts/B.java:17:6:17:14 | continue | stmts/B.java:11:4:11:17 | while (...) | +| stmts/B.java:19:6:19:20 | continue | stmts/B.java:6:3:6:26 | for (...) | +| stmts/B.java:22:6:22:11 | break | stmts/B.java:20:5:20:14 | switch (...) | +| stmts/B.java:24:6:24:17 | break | stmts/B.java:6:3:6:26 | for (...) | +| stmts/B.java:26:6:26:14 | continue | stmts/B.java:11:4:11:17 | while (...) | diff --git a/java/ql/test/library-tests/stmts/SwitchCases.expected b/java/ql/test/library-tests/stmts/SwitchCases.expected index 9bbb5fe61bf..e10bb74d654 100644 --- a/java/ql/test/library-tests/stmts/SwitchCases.expected +++ b/java/ql/test/library-tests/stmts/SwitchCases.expected @@ -1,6 +1,6 @@ -| stmts/A.java:6:3:6:10 | stmt | -| stmts/A.java:8:3:8:10 | stmt | -| stmts/A.java:10:3:10:10 | stmt | -| stmts/B.java:21:5:21:12 | stmt | -| stmts/B.java:23:5:23:12 | stmt | -| stmts/B.java:25:5:25:12 | stmt | \ No newline at end of file +| stmts/A.java:6:3:6:10 | case ... | +| stmts/A.java:8:3:8:10 | case ... | +| stmts/A.java:10:3:10:10 | default | +| stmts/B.java:21:5:21:12 | case ... | +| stmts/B.java:23:5:23:12 | case ... | +| stmts/B.java:25:5:25:12 | case ... | diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected index b5b5f262f47..2e465783264 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected @@ -1,30 +1,30 @@ -| CloseReaderTest.java:8:14:8:28 | stmt | CloseReaderTest.java:8:14:8:28 | super(...) | | CloseReaderTest.java:8:14:8:28 | super(...) | CloseReaderTest.java:8:14:8:28 | CloseReaderTest | -| CloseReaderTest.java:10:2:24:2 | stmt | CloseReaderTest.java:12:3:13:42 | stmt | +| CloseReaderTest.java:8:14:8:28 | { ... } | CloseReaderTest.java:8:14:8:28 | super(...) | +| CloseReaderTest.java:10:2:24:2 | { ... } | CloseReaderTest.java:12:3:13:42 | ...; | | CloseReaderTest.java:12:3:12:12 | System.out | CloseReaderTest.java:12:20:12:40 | "Enter password for " | -| CloseReaderTest.java:12:3:13:41 | print(...) | CloseReaderTest.java:14:3:14:21 | stmt | -| CloseReaderTest.java:12:3:13:42 | stmt | CloseReaderTest.java:12:3:12:12 | System.out | +| CloseReaderTest.java:12:3:13:41 | print(...) | CloseReaderTest.java:14:3:14:21 | ...; | +| CloseReaderTest.java:12:3:13:42 | ...; | CloseReaderTest.java:12:3:12:12 | System.out | | CloseReaderTest.java:12:20:12:40 | "Enter password for " | CloseReaderTest.java:12:44:12:50 | keyFile | | CloseReaderTest.java:12:20:12:50 | ... + ... | CloseReaderTest.java:13:7:13:40 | " (password will not be hidden): " | | CloseReaderTest.java:12:20:13:40 | ... + ... | CloseReaderTest.java:12:3:13:41 | print(...) | | CloseReaderTest.java:12:44:12:50 | keyFile | CloseReaderTest.java:12:20:12:50 | ... + ... | | CloseReaderTest.java:13:7:13:40 | " (password will not be hidden): " | CloseReaderTest.java:12:20:13:40 | ... + ... | | CloseReaderTest.java:14:3:14:12 | System.out | CloseReaderTest.java:14:3:14:20 | flush(...) | -| CloseReaderTest.java:14:3:14:20 | flush(...) | CloseReaderTest.java:15:3:16:16 | stmt | -| CloseReaderTest.java:14:3:14:21 | stmt | CloseReaderTest.java:14:3:14:12 | System.out | -| CloseReaderTest.java:15:3:16:16 | stmt | CloseReaderTest.java:16:5:16:13 | System.in | -| CloseReaderTest.java:15:18:16:15 | stdin | CloseReaderTest.java:17:3:23:3 | stmt | +| CloseReaderTest.java:14:3:14:20 | flush(...) | CloseReaderTest.java:15:3:16:16 | local variable declaration | +| CloseReaderTest.java:14:3:14:21 | ...; | CloseReaderTest.java:14:3:14:12 | System.out | +| CloseReaderTest.java:15:3:16:16 | local variable declaration | CloseReaderTest.java:16:5:16:13 | System.in | +| CloseReaderTest.java:15:18:16:15 | stdin | CloseReaderTest.java:17:3:23:3 | try ... | | CloseReaderTest.java:15:26:16:15 | new BufferedReader(...) | CloseReaderTest.java:15:18:16:15 | stdin | | CloseReaderTest.java:15:45:16:14 | new InputStreamReader(...) | CloseReaderTest.java:15:26:16:15 | new BufferedReader(...) | | CloseReaderTest.java:16:5:16:13 | System.in | CloseReaderTest.java:15:45:16:14 | new InputStreamReader(...) | -| CloseReaderTest.java:17:3:23:3 | stmt | CloseReaderTest.java:18:3:20:3 | stmt | -| CloseReaderTest.java:18:3:20:3 | stmt | CloseReaderTest.java:19:11:19:15 | stdin | -| CloseReaderTest.java:19:4:19:27 | stmt | CloseReaderTest.java:9:23:9:34 | readPassword | +| CloseReaderTest.java:17:3:23:3 | try ... | CloseReaderTest.java:18:3:20:3 | { ... } | +| CloseReaderTest.java:18:3:20:3 | { ... } | CloseReaderTest.java:19:11:19:15 | stdin | +| CloseReaderTest.java:19:4:19:27 | return ... | CloseReaderTest.java:9:23:9:34 | readPassword | | CloseReaderTest.java:19:11:19:15 | stdin | CloseReaderTest.java:19:11:19:26 | readLine(...) | -| CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:19:4:19:27 | stmt | -| CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:20:5:20:26 | stmt | -| CloseReaderTest.java:20:5:20:26 | stmt | CloseReaderTest.java:20:24:20:25 | ex | -| CloseReaderTest.java:20:24:20:25 | ex | CloseReaderTest.java:21:3:23:3 | stmt | -| CloseReaderTest.java:21:3:23:3 | stmt | CloseReaderTest.java:22:11:22:14 | null | -| CloseReaderTest.java:22:4:22:15 | stmt | CloseReaderTest.java:9:23:9:34 | readPassword | -| CloseReaderTest.java:22:11:22:14 | null | CloseReaderTest.java:22:4:22:15 | stmt | +| CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:19:4:19:27 | return ... | +| CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:20:5:20:26 | catch (...) | +| CloseReaderTest.java:20:5:20:26 | catch (...) | CloseReaderTest.java:20:24:20:25 | ex | +| CloseReaderTest.java:20:24:20:25 | ex | CloseReaderTest.java:21:3:23:3 | { ... } | +| CloseReaderTest.java:21:3:23:3 | { ... } | CloseReaderTest.java:22:11:22:14 | null | +| CloseReaderTest.java:22:4:22:15 | return ... | CloseReaderTest.java:9:23:9:34 | readPassword | +| CloseReaderTest.java:22:11:22:14 | null | CloseReaderTest.java:22:4:22:15 | return ... | diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/FalseSuccessors.expected b/java/ql/test/library-tests/successors/LoopVarReadTest/FalseSuccessors.expected index 3b2f6de1c72..5452af82eb5 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/FalseSuccessors.expected @@ -1 +1 @@ -| LoopVarReadTest.java:7:19:7:24 | ... < ... | LoopVarReadTest.java:12:3:12:13 | stmt | +| LoopVarReadTest.java:7:19:7:24 | ... < ... | LoopVarReadTest.java:12:3:12:13 | local variable declaration | diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected index f03586c25e8..a9e30fb2b7e 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected @@ -1,28 +1,28 @@ -| LoopVarReadTest.java:3:14:3:28 | stmt | LoopVarReadTest.java:3:14:3:28 | super(...) | | LoopVarReadTest.java:3:14:3:28 | super(...) | LoopVarReadTest.java:3:14:3:28 | LoopVarReadTest | -| LoopVarReadTest.java:5:2:15:2 | stmt | LoopVarReadTest.java:6:3:6:12 | stmt | -| LoopVarReadTest.java:6:3:6:12 | stmt | LoopVarReadTest.java:6:11:6:11 | 2 | -| LoopVarReadTest.java:6:7:6:11 | x | LoopVarReadTest.java:7:3:7:33 | stmt | +| LoopVarReadTest.java:3:14:3:28 | { ... } | LoopVarReadTest.java:3:14:3:28 | super(...) | +| LoopVarReadTest.java:5:2:15:2 | { ... } | LoopVarReadTest.java:6:3:6:12 | local variable declaration | +| LoopVarReadTest.java:6:3:6:12 | local variable declaration | LoopVarReadTest.java:6:11:6:11 | 2 | +| LoopVarReadTest.java:6:7:6:11 | x | LoopVarReadTest.java:7:3:7:33 | for (...) | | LoopVarReadTest.java:6:11:6:11 | 2 | LoopVarReadTest.java:6:7:6:11 | x | -| LoopVarReadTest.java:7:3:7:33 | stmt | LoopVarReadTest.java:7:16:7:16 | 0 | +| LoopVarReadTest.java:7:3:7:33 | for (...) | LoopVarReadTest.java:7:16:7:16 | 0 | | LoopVarReadTest.java:7:12:7:16 | y | LoopVarReadTest.java:7:19:7:19 | y | | LoopVarReadTest.java:7:16:7:16 | 0 | LoopVarReadTest.java:7:12:7:16 | y | | LoopVarReadTest.java:7:19:7:19 | y | LoopVarReadTest.java:7:23:7:24 | 10 | -| LoopVarReadTest.java:7:19:7:24 | ... < ... | LoopVarReadTest.java:8:3:10:3 | stmt | -| LoopVarReadTest.java:7:19:7:24 | ... < ... | LoopVarReadTest.java:12:3:12:13 | stmt | +| LoopVarReadTest.java:7:19:7:24 | ... < ... | LoopVarReadTest.java:8:3:10:3 | { ... } | +| LoopVarReadTest.java:7:19:7:24 | ... < ... | LoopVarReadTest.java:12:3:12:13 | local variable declaration | | LoopVarReadTest.java:7:23:7:24 | 10 | LoopVarReadTest.java:7:19:7:24 | ... < ... | | LoopVarReadTest.java:7:27:7:27 | y | LoopVarReadTest.java:7:32:7:32 | x | | LoopVarReadTest.java:7:27:7:32 | ...+=... | LoopVarReadTest.java:7:19:7:19 | y | | LoopVarReadTest.java:7:32:7:32 | x | LoopVarReadTest.java:7:27:7:32 | ...+=... | -| LoopVarReadTest.java:8:3:10:3 | stmt | LoopVarReadTest.java:9:4:9:29 | stmt | +| LoopVarReadTest.java:8:3:10:3 | { ... } | LoopVarReadTest.java:9:4:9:29 | ...; | | LoopVarReadTest.java:9:4:9:13 | System.out | LoopVarReadTest.java:9:23:9:27 | "Foo" | | LoopVarReadTest.java:9:4:9:28 | println(...) | LoopVarReadTest.java:7:27:7:27 | y | -| LoopVarReadTest.java:9:4:9:29 | stmt | LoopVarReadTest.java:9:4:9:13 | System.out | +| LoopVarReadTest.java:9:4:9:29 | ...; | LoopVarReadTest.java:9:4:9:13 | System.out | | LoopVarReadTest.java:9:23:9:27 | "Foo" | LoopVarReadTest.java:9:4:9:28 | println(...) | -| LoopVarReadTest.java:12:3:12:13 | stmt | LoopVarReadTest.java:12:11:12:12 | 10 | -| LoopVarReadTest.java:12:7:12:12 | q | LoopVarReadTest.java:14:3:14:28 | stmt | +| LoopVarReadTest.java:12:3:12:13 | local variable declaration | LoopVarReadTest.java:12:11:12:12 | 10 | +| LoopVarReadTest.java:12:7:12:12 | q | LoopVarReadTest.java:14:3:14:28 | ...; | | LoopVarReadTest.java:12:11:12:12 | 10 | LoopVarReadTest.java:12:7:12:12 | q | | LoopVarReadTest.java:14:3:14:12 | System.out | LoopVarReadTest.java:14:22:14:26 | "foo" | | LoopVarReadTest.java:14:3:14:27 | println(...) | LoopVarReadTest.java:4:21:4:28 | testLoop | -| LoopVarReadTest.java:14:3:14:28 | stmt | LoopVarReadTest.java:14:3:14:12 | System.out | +| LoopVarReadTest.java:14:3:14:28 | ...; | LoopVarReadTest.java:14:3:14:12 | System.out | | LoopVarReadTest.java:14:22:14:26 | "foo" | LoopVarReadTest.java:14:3:14:27 | println(...) | diff --git a/java/ql/test/library-tests/successors/SaveFileTest/FalseSuccessors.expected b/java/ql/test/library-tests/successors/SaveFileTest/FalseSuccessors.expected index 9a8ca853b27..b51304c1866 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/SaveFileTest/FalseSuccessors.expected @@ -1,2 +1,2 @@ -| SaveFileTest.java:18:7:18:26 | startsWith(...) | SaveFileTest.java:24:3:24:33 | stmt | -| SaveFileTest.java:34:11:34:54 | ... != ... | SaveFileTest.java:39:4:40:41 | stmt | +| SaveFileTest.java:18:7:18:26 | startsWith(...) | SaveFileTest.java:24:3:24:33 | local variable declaration | +| SaveFileTest.java:34:11:34:54 | ... != ... | SaveFileTest.java:39:4:40:41 | ...; | diff --git a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected index fe6dc51a0c9..3e4ca761fd1 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected @@ -1,26 +1,26 @@ -| SaveFileTest.java:11:14:11:25 | stmt | SaveFileTest.java:11:14:11:25 | super(...) | | SaveFileTest.java:11:14:11:25 | super(...) | SaveFileTest.java:11:14:11:25 | SaveFileTest | -| SaveFileTest.java:15:2:55:2 | stmt | SaveFileTest.java:17:3:17:25 | stmt | -| SaveFileTest.java:17:3:17:25 | stmt | SaveFileTest.java:17:21:17:24 | path | -| SaveFileTest.java:17:10:17:24 | savePath | SaveFileTest.java:18:3:18:27 | stmt | +| SaveFileTest.java:11:14:11:25 | { ... } | SaveFileTest.java:11:14:11:25 | super(...) | +| SaveFileTest.java:15:2:55:2 | { ... } | SaveFileTest.java:17:3:17:25 | local variable declaration | +| SaveFileTest.java:17:3:17:25 | local variable declaration | SaveFileTest.java:17:21:17:24 | path | +| SaveFileTest.java:17:10:17:24 | savePath | SaveFileTest.java:18:3:18:27 | if (...) | | SaveFileTest.java:17:21:17:24 | path | SaveFileTest.java:17:10:17:24 | savePath | -| SaveFileTest.java:18:3:18:27 | stmt | SaveFileTest.java:18:7:18:10 | path | +| SaveFileTest.java:18:3:18:27 | if (...) | SaveFileTest.java:18:7:18:10 | path | | SaveFileTest.java:18:7:18:10 | path | SaveFileTest.java:18:23:18:25 | "/" | -| SaveFileTest.java:18:7:18:26 | startsWith(...) | SaveFileTest.java:19:3:21:3 | stmt | -| SaveFileTest.java:18:7:18:26 | startsWith(...) | SaveFileTest.java:24:3:24:33 | stmt | +| SaveFileTest.java:18:7:18:26 | startsWith(...) | SaveFileTest.java:19:3:21:3 | { ... } | +| SaveFileTest.java:18:7:18:26 | startsWith(...) | SaveFileTest.java:24:3:24:33 | local variable declaration | | SaveFileTest.java:18:23:18:25 | "/" | SaveFileTest.java:18:7:18:26 | startsWith(...) | -| SaveFileTest.java:19:3:21:3 | stmt | SaveFileTest.java:20:4:20:32 | stmt | -| SaveFileTest.java:20:4:20:31 | ...=... | SaveFileTest.java:24:3:24:33 | stmt | -| SaveFileTest.java:20:4:20:32 | stmt | SaveFileTest.java:20:15:20:18 | path | +| SaveFileTest.java:19:3:21:3 | { ... } | SaveFileTest.java:20:4:20:32 | ...; | +| SaveFileTest.java:20:4:20:31 | ...=... | SaveFileTest.java:24:3:24:33 | local variable declaration | +| SaveFileTest.java:20:4:20:32 | ...; | SaveFileTest.java:20:15:20:18 | path | | SaveFileTest.java:20:15:20:18 | path | SaveFileTest.java:20:30:20:30 | 1 | | SaveFileTest.java:20:15:20:31 | substring(...) | SaveFileTest.java:20:4:20:31 | ...=... | | SaveFileTest.java:20:30:20:30 | 1 | SaveFileTest.java:20:15:20:31 | substring(...) | -| SaveFileTest.java:24:3:24:33 | stmt | SaveFileTest.java:24:27:24:31 | "foo" | -| SaveFileTest.java:24:8:24:32 | dirPath | SaveFileTest.java:25:3:26:16 | stmt | +| SaveFileTest.java:24:3:24:33 | local variable declaration | SaveFileTest.java:24:27:24:31 | "foo" | +| SaveFileTest.java:24:8:24:32 | dirPath | SaveFileTest.java:25:3:26:16 | local variable declaration | | SaveFileTest.java:24:18:24:32 | new File(...) | SaveFileTest.java:24:8:24:32 | dirPath | | SaveFileTest.java:24:27:24:31 | "foo" | SaveFileTest.java:24:18:24:32 | new File(...) | -| SaveFileTest.java:25:3:26:16 | stmt | SaveFileTest.java:25:28:25:34 | dirPath | -| SaveFileTest.java:25:8:26:15 | saveFile | SaveFileTest.java:28:3:28:33 | stmt | +| SaveFileTest.java:25:3:26:16 | local variable declaration | SaveFileTest.java:25:28:25:34 | dirPath | +| SaveFileTest.java:25:8:26:15 | saveFile | SaveFileTest.java:28:3:28:33 | local variable declaration | | SaveFileTest.java:25:19:26:15 | new File(...) | SaveFileTest.java:25:8:26:15 | saveFile | | SaveFileTest.java:25:28:25:34 | dirPath | SaveFileTest.java:25:28:25:52 | getAbsolutePath(...) | | SaveFileTest.java:25:28:25:52 | getAbsolutePath(...) | SaveFileTest.java:25:56:25:69 | File.separator | @@ -28,76 +28,76 @@ | SaveFileTest.java:25:28:26:14 | ... + ... | SaveFileTest.java:25:19:26:15 | new File(...) | | SaveFileTest.java:25:56:25:69 | File.separator | SaveFileTest.java:25:28:25:69 | ... + ... | | SaveFileTest.java:26:7:26:14 | savePath | SaveFileTest.java:25:28:26:14 | ... + ... | -| SaveFileTest.java:28:3:28:33 | stmt | SaveFileTest.java:28:28:28:31 | 8192 | -| SaveFileTest.java:28:10:28:32 | buffer | SaveFileTest.java:29:3:29:20 | stmt | +| SaveFileTest.java:28:3:28:33 | local variable declaration | SaveFileTest.java:28:28:28:31 | 8192 | +| SaveFileTest.java:28:10:28:32 | buffer | SaveFileTest.java:29:3:29:20 | local variable declaration | | SaveFileTest.java:28:19:28:32 | new byte[] | SaveFileTest.java:28:10:28:32 | buffer | | SaveFileTest.java:28:28:28:31 | 8192 | SaveFileTest.java:28:19:28:32 | new byte[] | -| SaveFileTest.java:29:3:29:20 | stmt | SaveFileTest.java:29:19:29:19 | 0 | -| SaveFileTest.java:29:7:29:19 | bytesRead | SaveFileTest.java:30:3:30:26 | stmt | +| SaveFileTest.java:29:3:29:20 | local variable declaration | SaveFileTest.java:29:19:29:19 | 0 | +| SaveFileTest.java:29:7:29:19 | bytesRead | SaveFileTest.java:30:3:30:26 | local variable declaration | | SaveFileTest.java:29:19:29:19 | 0 | SaveFileTest.java:29:7:29:19 | bytesRead | -| SaveFileTest.java:30:3:30:26 | stmt | SaveFileTest.java:30:22:30:25 | null | -| SaveFileTest.java:30:16:30:25 | bos | SaveFileTest.java:31:3:53:3 | stmt | +| SaveFileTest.java:30:3:30:26 | local variable declaration | SaveFileTest.java:30:22:30:25 | null | +| SaveFileTest.java:30:16:30:25 | bos | SaveFileTest.java:31:3:53:3 | try ... | | SaveFileTest.java:30:22:30:25 | null | SaveFileTest.java:30:16:30:25 | bos | -| SaveFileTest.java:31:3:53:3 | stmt | SaveFileTest.java:32:3:41:3 | stmt | -| SaveFileTest.java:32:3:41:3 | stmt | SaveFileTest.java:33:4:33:40 | stmt | -| SaveFileTest.java:33:4:33:39 | ...=... | SaveFileTest.java:34:4:34:55 | stmt | -| SaveFileTest.java:33:4:33:40 | stmt | SaveFileTest.java:33:31:33:38 | saveFile | +| SaveFileTest.java:31:3:53:3 | try ... | SaveFileTest.java:32:3:41:3 | { ... } | +| SaveFileTest.java:32:3:41:3 | { ... } | SaveFileTest.java:33:4:33:40 | ...; | +| SaveFileTest.java:33:4:33:39 | ...=... | SaveFileTest.java:34:4:34:55 | while (...) | +| SaveFileTest.java:33:4:33:40 | ...; | SaveFileTest.java:33:31:33:38 | saveFile | | SaveFileTest.java:33:10:33:39 | new FileOutputStream(...) | SaveFileTest.java:33:4:33:39 | ...=... | -| SaveFileTest.java:33:10:33:39 | new FileOutputStream(...) | SaveFileTest.java:41:5:41:23 | stmt | -| SaveFileTest.java:33:10:33:39 | new FileOutputStream(...) | SaveFileTest.java:45:3:53:3 | stmt | +| SaveFileTest.java:33:10:33:39 | new FileOutputStream(...) | SaveFileTest.java:41:5:41:23 | catch (...) | +| SaveFileTest.java:33:10:33:39 | new FileOutputStream(...) | SaveFileTest.java:45:3:53:3 | { ... } | | SaveFileTest.java:33:31:33:38 | saveFile | SaveFileTest.java:33:10:33:39 | new FileOutputStream(...) | -| SaveFileTest.java:34:4:34:55 | stmt | SaveFileTest.java:34:24:34:25 | is | -| SaveFileTest.java:34:11:34:54 | ... != ... | SaveFileTest.java:35:4:37:4 | stmt | -| SaveFileTest.java:34:11:34:54 | ... != ... | SaveFileTest.java:39:4:40:41 | stmt | +| SaveFileTest.java:34:4:34:55 | while (...) | SaveFileTest.java:34:24:34:25 | is | +| SaveFileTest.java:34:11:34:54 | ... != ... | SaveFileTest.java:35:4:37:4 | { ... } | +| SaveFileTest.java:34:11:34:54 | ... != ... | SaveFileTest.java:39:4:40:41 | ...; | | SaveFileTest.java:34:12:34:47 | ...=... | SaveFileTest.java:34:54:34:54 | 1 | | SaveFileTest.java:34:24:34:25 | is | SaveFileTest.java:34:32:34:37 | buffer | | SaveFileTest.java:34:24:34:47 | read(...) | SaveFileTest.java:34:12:34:47 | ...=... | -| SaveFileTest.java:34:24:34:47 | read(...) | SaveFileTest.java:41:5:41:23 | stmt | -| SaveFileTest.java:34:24:34:47 | read(...) | SaveFileTest.java:45:3:53:3 | stmt | +| SaveFileTest.java:34:24:34:47 | read(...) | SaveFileTest.java:41:5:41:23 | catch (...) | +| SaveFileTest.java:34:24:34:47 | read(...) | SaveFileTest.java:45:3:53:3 | { ... } | | SaveFileTest.java:34:32:34:37 | buffer | SaveFileTest.java:34:40:34:40 | 0 | | SaveFileTest.java:34:40:34:40 | 0 | SaveFileTest.java:34:43:34:46 | 8192 | | SaveFileTest.java:34:43:34:46 | 8192 | SaveFileTest.java:34:24:34:47 | read(...) | | SaveFileTest.java:34:53:34:54 | -... | SaveFileTest.java:34:11:34:54 | ... != ... | | SaveFileTest.java:34:54:34:54 | 1 | SaveFileTest.java:34:53:34:54 | -... | -| SaveFileTest.java:35:4:37:4 | stmt | SaveFileTest.java:36:5:36:36 | stmt | +| SaveFileTest.java:35:4:37:4 | { ... } | SaveFileTest.java:36:5:36:36 | ...; | | SaveFileTest.java:36:5:36:7 | bos | SaveFileTest.java:36:15:36:20 | buffer | | SaveFileTest.java:36:5:36:35 | write(...) | SaveFileTest.java:34:24:34:25 | is | -| SaveFileTest.java:36:5:36:35 | write(...) | SaveFileTest.java:41:5:41:23 | stmt | -| SaveFileTest.java:36:5:36:35 | write(...) | SaveFileTest.java:45:3:53:3 | stmt | -| SaveFileTest.java:36:5:36:36 | stmt | SaveFileTest.java:36:5:36:7 | bos | +| SaveFileTest.java:36:5:36:35 | write(...) | SaveFileTest.java:41:5:41:23 | catch (...) | +| SaveFileTest.java:36:5:36:35 | write(...) | SaveFileTest.java:45:3:53:3 | { ... } | +| SaveFileTest.java:36:5:36:36 | ...; | SaveFileTest.java:36:5:36:7 | bos | | SaveFileTest.java:36:15:36:20 | buffer | SaveFileTest.java:36:23:36:23 | 0 | | SaveFileTest.java:36:23:36:23 | 0 | SaveFileTest.java:36:26:36:34 | bytesRead | | SaveFileTest.java:36:26:36:34 | bytesRead | SaveFileTest.java:36:5:36:35 | write(...) | | SaveFileTest.java:39:4:39:13 | System.out | SaveFileTest.java:39:23:39:54 | "The file has been written to [" | -| SaveFileTest.java:39:4:40:40 | println(...) | SaveFileTest.java:41:5:41:23 | stmt | -| SaveFileTest.java:39:4:40:40 | println(...) | SaveFileTest.java:45:3:53:3 | stmt | -| SaveFileTest.java:39:4:40:41 | stmt | SaveFileTest.java:39:4:39:13 | System.out | +| SaveFileTest.java:39:4:40:40 | println(...) | SaveFileTest.java:41:5:41:23 | catch (...) | +| SaveFileTest.java:39:4:40:40 | println(...) | SaveFileTest.java:45:3:53:3 | { ... } | +| SaveFileTest.java:39:4:40:41 | ...; | SaveFileTest.java:39:4:39:13 | System.out | | SaveFileTest.java:39:23:39:54 | "The file has been written to [" | SaveFileTest.java:40:8:40:15 | saveFile | | SaveFileTest.java:39:23:40:33 | ... + ... | SaveFileTest.java:40:37:40:39 | "]" | | SaveFileTest.java:39:23:40:39 | ... + ... | SaveFileTest.java:39:4:40:40 | println(...) | | SaveFileTest.java:40:8:40:15 | saveFile | SaveFileTest.java:40:8:40:33 | getAbsolutePath(...) | | SaveFileTest.java:40:8:40:33 | getAbsolutePath(...) | SaveFileTest.java:39:23:40:33 | ... + ... | -| SaveFileTest.java:40:8:40:33 | getAbsolutePath(...) | SaveFileTest.java:41:5:41:23 | stmt | -| SaveFileTest.java:40:8:40:33 | getAbsolutePath(...) | SaveFileTest.java:45:3:53:3 | stmt | +| SaveFileTest.java:40:8:40:33 | getAbsolutePath(...) | SaveFileTest.java:41:5:41:23 | catch (...) | +| SaveFileTest.java:40:8:40:33 | getAbsolutePath(...) | SaveFileTest.java:45:3:53:3 | { ... } | | SaveFileTest.java:40:37:40:39 | "]" | SaveFileTest.java:39:23:40:39 | ... + ... | -| SaveFileTest.java:41:5:41:23 | stmt | SaveFileTest.java:41:22:41:22 | e | -| SaveFileTest.java:41:22:41:22 | e | SaveFileTest.java:42:3:44:3 | stmt | -| SaveFileTest.java:42:3:44:3 | stmt | SaveFileTest.java:43:26:43:47 | "ERROR uploading file" | -| SaveFileTest.java:43:4:43:52 | stmt | SaveFileTest.java:45:3:53:3 | stmt | -| SaveFileTest.java:43:10:43:51 | new IOException(...) | SaveFileTest.java:43:4:43:52 | stmt | +| SaveFileTest.java:41:5:41:23 | catch (...) | SaveFileTest.java:41:22:41:22 | e | +| SaveFileTest.java:41:22:41:22 | e | SaveFileTest.java:42:3:44:3 | { ... } | +| SaveFileTest.java:42:3:44:3 | { ... } | SaveFileTest.java:43:26:43:47 | "ERROR uploading file" | +| SaveFileTest.java:43:4:43:52 | throw ... | SaveFileTest.java:45:3:53:3 | { ... } | +| SaveFileTest.java:43:10:43:51 | new IOException(...) | SaveFileTest.java:43:4:43:52 | throw ... | | SaveFileTest.java:43:26:43:47 | "ERROR uploading file" | SaveFileTest.java:43:50:43:50 | e | | SaveFileTest.java:43:50:43:50 | e | SaveFileTest.java:43:10:43:51 | new IOException(...) | -| SaveFileTest.java:45:3:53:3 | stmt | SaveFileTest.java:46:4:52:4 | stmt | -| SaveFileTest.java:46:4:52:4 | stmt | SaveFileTest.java:47:4:50:4 | stmt | -| SaveFileTest.java:47:4:50:4 | stmt | SaveFileTest.java:48:5:48:16 | stmt | +| SaveFileTest.java:45:3:53:3 | { ... } | SaveFileTest.java:46:4:52:4 | try ... | +| SaveFileTest.java:46:4:52:4 | try ... | SaveFileTest.java:47:4:50:4 | { ... } | +| SaveFileTest.java:47:4:50:4 | { ... } | SaveFileTest.java:48:5:48:16 | ...; | | SaveFileTest.java:48:5:48:7 | bos | SaveFileTest.java:48:5:48:15 | flush(...) | -| SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:49:5:49:16 | stmt | -| SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:50:6:50:30 | stmt | -| SaveFileTest.java:48:5:48:16 | stmt | SaveFileTest.java:48:5:48:7 | bos | +| SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:49:5:49:16 | ...; | +| SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:50:6:50:30 | catch (...) | +| SaveFileTest.java:48:5:48:16 | ...; | SaveFileTest.java:48:5:48:7 | bos | | SaveFileTest.java:49:5:49:7 | bos | SaveFileTest.java:49:5:49:15 | close(...) | | SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:12:14:12:21 | saveFile | -| SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:50:6:50:30 | stmt | -| SaveFileTest.java:49:5:49:16 | stmt | SaveFileTest.java:49:5:49:7 | bos | -| SaveFileTest.java:50:6:50:30 | stmt | SaveFileTest.java:50:23:50:29 | ignored | -| SaveFileTest.java:50:23:50:29 | ignored | SaveFileTest.java:51:4:52:4 | stmt | -| SaveFileTest.java:51:4:52:4 | stmt | SaveFileTest.java:12:14:12:21 | saveFile | +| SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:50:6:50:30 | catch (...) | +| SaveFileTest.java:49:5:49:16 | ...; | SaveFileTest.java:49:5:49:7 | bos | +| SaveFileTest.java:50:6:50:30 | catch (...) | SaveFileTest.java:50:23:50:29 | ignored | +| SaveFileTest.java:50:23:50:29 | ignored | SaveFileTest.java:51:4:52:4 | { ... } | +| SaveFileTest.java:51:4:52:4 | { ... } | SaveFileTest.java:12:14:12:21 | saveFile | diff --git a/java/ql/test/library-tests/successors/SchackTest/FalseSuccessors.expected b/java/ql/test/library-tests/successors/SchackTest/FalseSuccessors.expected index 1a8a401b08e..fb487c6715b 100644 --- a/java/ql/test/library-tests/successors/SchackTest/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/SchackTest/FalseSuccessors.expected @@ -1,6 +1,6 @@ -| SchackTest.java:8:9:8:12 | ... == ... | SchackTest.java:10:5:10:13 | stmt | -| SchackTest.java:10:9:10:12 | ... == ... | SchackTest.java:12:14:15:4 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:16:4:16:41 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:17:5:17:17 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:21:13:23:3 | stmt | +| SchackTest.java:8:9:8:12 | ... == ... | SchackTest.java:10:5:10:13 | if (...) | +| SchackTest.java:10:9:10:12 | ... == ... | SchackTest.java:12:14:15:4 | { ... } | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:16:4:16:41 | ...; | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:17:5:17:17 | catch (...) | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:21:13:23:3 | { ... } | | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:29:10:29:22 | random(...) | diff --git a/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected b/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected index 9cd1d76f24f..5137de0a73f 100644 --- a/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected @@ -1,73 +1,73 @@ -| SchackTest.java:1:14:1:23 | stmt | SchackTest.java:1:14:1:23 | super(...) | | SchackTest.java:1:14:1:23 | super(...) | SchackTest.java:1:14:1:23 | SchackTest | -| SchackTest.java:2:8:2:10 | stmt | SchackTest.java:2:8:2:10 | super(...) | +| SchackTest.java:1:14:1:23 | { ... } | SchackTest.java:1:14:1:23 | super(...) | | SchackTest.java:2:8:2:10 | super(...) | SchackTest.java:2:8:2:10 | ExA | -| SchackTest.java:3:8:3:10 | stmt | SchackTest.java:3:8:3:10 | super(...) | +| SchackTest.java:2:8:2:10 | { ... } | SchackTest.java:2:8:2:10 | super(...) | | SchackTest.java:3:8:3:10 | super(...) | SchackTest.java:3:8:3:10 | ExB | -| SchackTest.java:5:18:24:2 | stmt | SchackTest.java:6:3:23:3 | stmt | -| SchackTest.java:6:3:23:3 | stmt | SchackTest.java:6:7:17:3 | stmt | -| SchackTest.java:6:7:17:3 | stmt | SchackTest.java:7:4:15:4 | stmt | -| SchackTest.java:7:4:15:4 | stmt | SchackTest.java:7:8:12:4 | stmt | -| SchackTest.java:7:8:12:4 | stmt | SchackTest.java:8:5:8:13 | stmt | -| SchackTest.java:8:5:8:13 | stmt | SchackTest.java:8:9:8:9 | x | +| SchackTest.java:3:8:3:10 | { ... } | SchackTest.java:3:8:3:10 | super(...) | +| SchackTest.java:5:18:24:2 | { ... } | SchackTest.java:6:3:23:3 | try ... | +| SchackTest.java:6:3:23:3 | try ... | SchackTest.java:6:7:17:3 | { ... } | +| SchackTest.java:6:7:17:3 | { ... } | SchackTest.java:7:4:15:4 | try ... | +| SchackTest.java:7:4:15:4 | try ... | SchackTest.java:7:8:12:4 | { ... } | +| SchackTest.java:7:8:12:4 | { ... } | SchackTest.java:8:5:8:13 | if (...) | +| SchackTest.java:8:5:8:13 | if (...) | SchackTest.java:8:9:8:9 | x | | SchackTest.java:8:9:8:9 | x | SchackTest.java:8:12:8:12 | 1 | | SchackTest.java:8:9:8:12 | ... == ... | SchackTest.java:9:12:9:20 | new ExA(...) | -| SchackTest.java:8:9:8:12 | ... == ... | SchackTest.java:10:5:10:13 | stmt | +| SchackTest.java:8:9:8:12 | ... == ... | SchackTest.java:10:5:10:13 | if (...) | | SchackTest.java:8:12:8:12 | 1 | SchackTest.java:8:9:8:12 | ... == ... | -| SchackTest.java:9:6:9:21 | stmt | SchackTest.java:12:14:15:4 | stmt | -| SchackTest.java:9:12:9:20 | new ExA(...) | SchackTest.java:9:6:9:21 | stmt | -| SchackTest.java:9:12:9:20 | new ExA(...) | SchackTest.java:12:14:15:4 | stmt | -| SchackTest.java:10:5:10:13 | stmt | SchackTest.java:10:9:10:9 | x | +| SchackTest.java:9:6:9:21 | throw ... | SchackTest.java:12:14:15:4 | { ... } | +| SchackTest.java:9:12:9:20 | new ExA(...) | SchackTest.java:9:6:9:21 | throw ... | +| SchackTest.java:9:12:9:20 | new ExA(...) | SchackTest.java:12:14:15:4 | { ... } | +| SchackTest.java:10:5:10:13 | if (...) | SchackTest.java:10:9:10:9 | x | | SchackTest.java:10:9:10:9 | x | SchackTest.java:10:12:10:12 | 2 | -| SchackTest.java:10:9:10:12 | ... == ... | SchackTest.java:11:6:11:12 | stmt | -| SchackTest.java:10:9:10:12 | ... == ... | SchackTest.java:12:14:15:4 | stmt | +| SchackTest.java:10:9:10:12 | ... == ... | SchackTest.java:11:6:11:12 | return ... | +| SchackTest.java:10:9:10:12 | ... == ... | SchackTest.java:12:14:15:4 | { ... } | | SchackTest.java:10:12:10:12 | 2 | SchackTest.java:10:9:10:12 | ... == ... | -| SchackTest.java:11:6:11:12 | stmt | SchackTest.java:12:14:15:4 | stmt | -| SchackTest.java:12:14:15:4 | stmt | SchackTest.java:13:5:13:14 | stmt | -| SchackTest.java:13:5:13:14 | stmt | SchackTest.java:13:9:13:13 | bar(...) | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:14:6:14:42 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:16:4:16:41 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:17:5:17:17 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:19:5:19:17 | stmt | -| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:21:13:23:3 | stmt | +| SchackTest.java:11:6:11:12 | return ... | SchackTest.java:12:14:15:4 | { ... } | +| SchackTest.java:12:14:15:4 | { ... } | SchackTest.java:13:5:13:14 | if (...) | +| SchackTest.java:13:5:13:14 | if (...) | SchackTest.java:13:9:13:13 | bar(...) | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:14:6:14:42 | ...; | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:16:4:16:41 | ...; | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:17:5:17:17 | catch (...) | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:19:5:19:17 | catch (...) | +| SchackTest.java:13:9:13:13 | bar(...) | SchackTest.java:21:13:23:3 | { ... } | | SchackTest.java:14:6:14:15 | System.out | SchackTest.java:14:25:14:40 | "true successor" | -| SchackTest.java:14:6:14:41 | println(...) | SchackTest.java:16:4:16:41 | stmt | -| SchackTest.java:14:6:14:41 | println(...) | SchackTest.java:17:5:17:17 | stmt | -| SchackTest.java:14:6:14:41 | println(...) | SchackTest.java:21:13:23:3 | stmt | -| SchackTest.java:14:6:14:42 | stmt | SchackTest.java:14:6:14:15 | System.out | +| SchackTest.java:14:6:14:41 | println(...) | SchackTest.java:16:4:16:41 | ...; | +| SchackTest.java:14:6:14:41 | println(...) | SchackTest.java:17:5:17:17 | catch (...) | +| SchackTest.java:14:6:14:41 | println(...) | SchackTest.java:21:13:23:3 | { ... } | +| SchackTest.java:14:6:14:42 | ...; | SchackTest.java:14:6:14:15 | System.out | | SchackTest.java:14:25:14:40 | "true successor" | SchackTest.java:14:6:14:41 | println(...) | | SchackTest.java:16:4:16:13 | System.out | SchackTest.java:16:23:16:39 | "false successor" | -| SchackTest.java:16:4:16:40 | println(...) | SchackTest.java:21:13:23:3 | stmt | -| SchackTest.java:16:4:16:41 | stmt | SchackTest.java:16:4:16:13 | System.out | +| SchackTest.java:16:4:16:40 | println(...) | SchackTest.java:21:13:23:3 | { ... } | +| SchackTest.java:16:4:16:41 | ...; | SchackTest.java:16:4:16:13 | System.out | | SchackTest.java:16:23:16:39 | "false successor" | SchackTest.java:16:4:16:40 | println(...) | -| SchackTest.java:17:5:17:17 | stmt | SchackTest.java:17:16:17:16 | e | -| SchackTest.java:17:16:17:16 | e | SchackTest.java:17:19:19:3 | stmt | -| SchackTest.java:17:19:19:3 | stmt | SchackTest.java:18:4:18:41 | stmt | +| SchackTest.java:17:5:17:17 | catch (...) | SchackTest.java:17:16:17:16 | e | +| SchackTest.java:17:16:17:16 | e | SchackTest.java:17:19:19:3 | { ... } | +| SchackTest.java:17:19:19:3 | { ... } | SchackTest.java:18:4:18:41 | ...; | | SchackTest.java:18:4:18:13 | System.out | SchackTest.java:18:23:18:39 | "false successor" | -| SchackTest.java:18:4:18:40 | println(...) | SchackTest.java:21:13:23:3 | stmt | -| SchackTest.java:18:4:18:41 | stmt | SchackTest.java:18:4:18:13 | System.out | +| SchackTest.java:18:4:18:40 | println(...) | SchackTest.java:21:13:23:3 | { ... } | +| SchackTest.java:18:4:18:41 | ...; | SchackTest.java:18:4:18:13 | System.out | | SchackTest.java:18:23:18:39 | "false successor" | SchackTest.java:18:4:18:40 | println(...) | -| SchackTest.java:19:5:19:17 | stmt | SchackTest.java:19:16:19:16 | e | -| SchackTest.java:19:16:19:16 | e | SchackTest.java:19:19:21:3 | stmt | -| SchackTest.java:19:19:21:3 | stmt | SchackTest.java:20:4:20:74 | stmt | +| SchackTest.java:19:5:19:17 | catch (...) | SchackTest.java:19:16:19:16 | e | +| SchackTest.java:19:16:19:16 | e | SchackTest.java:19:19:21:3 | { ... } | +| SchackTest.java:19:19:21:3 | { ... } | SchackTest.java:20:4:20:74 | ...; | | SchackTest.java:20:4:20:13 | System.out | SchackTest.java:20:23:20:72 | "successor (but neither true nor false successor)" | -| SchackTest.java:20:4:20:73 | println(...) | SchackTest.java:21:13:23:3 | stmt | -| SchackTest.java:20:4:20:74 | stmt | SchackTest.java:20:4:20:13 | System.out | +| SchackTest.java:20:4:20:73 | println(...) | SchackTest.java:21:13:23:3 | { ... } | +| SchackTest.java:20:4:20:74 | ...; | SchackTest.java:20:4:20:13 | System.out | | SchackTest.java:20:23:20:72 | "successor (but neither true nor false successor)" | SchackTest.java:20:4:20:73 | println(...) | -| SchackTest.java:21:13:23:3 | stmt | SchackTest.java:22:4:22:41 | stmt | +| SchackTest.java:21:13:23:3 | { ... } | SchackTest.java:22:4:22:41 | ...; | | SchackTest.java:22:4:22:13 | System.out | SchackTest.java:22:23:22:39 | "false successor" | | SchackTest.java:22:4:22:40 | println(...) | SchackTest.java:5:7:5:9 | foo | -| SchackTest.java:22:4:22:41 | stmt | SchackTest.java:22:4:22:13 | System.out | +| SchackTest.java:22:4:22:41 | ...; | SchackTest.java:22:4:22:13 | System.out | | SchackTest.java:22:23:22:39 | "false successor" | SchackTest.java:22:4:22:40 | println(...) | -| SchackTest.java:26:35:30:2 | stmt | SchackTest.java:27:3:27:25 | stmt | -| SchackTest.java:27:3:27:25 | stmt | SchackTest.java:27:7:27:19 | random(...) | +| SchackTest.java:26:35:30:2 | { ... } | SchackTest.java:27:3:27:25 | if (...) | +| SchackTest.java:27:3:27:25 | if (...) | SchackTest.java:27:7:27:19 | random(...) | | SchackTest.java:27:7:27:19 | random(...) | SchackTest.java:27:23:27:24 | .5 | | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:28:10:28:18 | new ExB(...) | | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:29:10:29:22 | random(...) | | SchackTest.java:27:23:27:24 | .5 | SchackTest.java:27:7:27:24 | ... > ... | -| SchackTest.java:28:4:28:19 | stmt | SchackTest.java:26:18:26:20 | bar | -| SchackTest.java:28:10:28:18 | new ExB(...) | SchackTest.java:28:4:28:19 | stmt | -| SchackTest.java:29:3:29:28 | stmt | SchackTest.java:26:18:26:20 | bar | +| SchackTest.java:28:4:28:19 | throw ... | SchackTest.java:26:18:26:20 | bar | +| SchackTest.java:28:10:28:18 | new ExB(...) | SchackTest.java:28:4:28:19 | throw ... | +| SchackTest.java:29:3:29:28 | return ... | SchackTest.java:26:18:26:20 | bar | | SchackTest.java:29:10:29:22 | random(...) | SchackTest.java:29:26:29:27 | .3 | -| SchackTest.java:29:10:29:27 | ... > ... | SchackTest.java:29:3:29:28 | stmt | +| SchackTest.java:29:10:29:27 | ... > ... | SchackTest.java:29:3:29:28 | return ... | | SchackTest.java:29:26:29:27 | .3 | SchackTest.java:29:10:29:27 | ... > ... | diff --git a/java/ql/test/library-tests/successors/TestBreak/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestBreak/FalseSuccessors.expected index 0cf3efedda5..8a8db779bd0 100644 --- a/java/ql/test/library-tests/successors/TestBreak/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestBreak/FalseSuccessors.expected @@ -1,5 +1,5 @@ -| TestBreak.java:12:9:12:14 | ... == ... | TestBreak.java:16:5:27:5 | stmt | -| TestBreak.java:19:11:19:16 | ... == ... | TestBreak.java:23:7:25:7 | stmt | -| TestBreak.java:32:8:32:13 | ... == ... | TestBreak.java:36:4:46:4 | stmt | -| TestBreak.java:39:10:39:15 | ... == ... | TestBreak.java:43:6:43:15 | stmt | -| TestBreak.java:44:14:44:19 | ... == ... | TestBreak.java:45:5:45:11 | stmt | +| TestBreak.java:12:9:12:14 | ... == ... | TestBreak.java:16:5:27:5 | { ... } | +| TestBreak.java:19:11:19:16 | ... == ... | TestBreak.java:23:7:25:7 | { ... } | +| TestBreak.java:32:8:32:13 | ... == ... | TestBreak.java:36:4:46:4 | { ... } | +| TestBreak.java:39:10:39:15 | ... == ... | TestBreak.java:43:6:43:15 | ...; | +| TestBreak.java:44:14:44:19 | ... == ... | TestBreak.java:45:5:45:11 | ...; | diff --git a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected index bfc01664042..3e08d2159f1 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected @@ -1,155 +1,155 @@ -| TestBreak.java:3:14:3:22 | stmt | TestBreak.java:3:14:3:22 | super(...) | | TestBreak.java:3:14:3:22 | super(...) | TestBreak.java:3:14:3:22 | TestBreak | -| TestBreak.java:5:2:85:2 | stmt | TestBreak.java:7:3:8:11 | stmt | -| TestBreak.java:7:3:8:11 | stmt | TestBreak.java:8:4:8:11 | stmt | -| TestBreak.java:8:4:8:11 | stmt | TestBreak.java:9:4:28:4 | stmt | -| TestBreak.java:9:4:28:4 | stmt | TestBreak.java:10:5:10:14 | stmt | -| TestBreak.java:10:5:10:14 | stmt | TestBreak.java:10:13:10:13 | 1 | -| TestBreak.java:10:9:10:13 | x | TestBreak.java:11:5:11:14 | stmt | +| TestBreak.java:3:14:3:22 | { ... } | TestBreak.java:3:14:3:22 | super(...) | +| TestBreak.java:5:2:85:2 | { ... } | TestBreak.java:7:3:8:11 | labeled statement | +| TestBreak.java:7:3:8:11 | labeled statement | TestBreak.java:8:4:8:11 | for (...) | +| TestBreak.java:8:4:8:11 | for (...) | TestBreak.java:9:4:28:4 | { ... } | +| TestBreak.java:9:4:28:4 | { ... } | TestBreak.java:10:5:10:14 | local variable declaration | +| TestBreak.java:10:5:10:14 | local variable declaration | TestBreak.java:10:13:10:13 | 1 | +| TestBreak.java:10:9:10:13 | x | TestBreak.java:11:5:11:14 | ...; | | TestBreak.java:10:13:10:13 | 1 | TestBreak.java:10:9:10:13 | x | -| TestBreak.java:11:5:11:13 | ...=... | TestBreak.java:12:5:12:15 | stmt | -| TestBreak.java:11:5:11:14 | stmt | TestBreak.java:11:9:11:9 | x | +| TestBreak.java:11:5:11:13 | ...=... | TestBreak.java:12:5:12:15 | if (...) | +| TestBreak.java:11:5:11:14 | ...; | TestBreak.java:11:9:11:9 | x | | TestBreak.java:11:9:11:9 | x | TestBreak.java:11:13:11:13 | 1 | | TestBreak.java:11:9:11:13 | ... + ... | TestBreak.java:11:5:11:13 | ...=... | | TestBreak.java:11:13:11:13 | 1 | TestBreak.java:11:9:11:13 | ... + ... | -| TestBreak.java:12:5:12:15 | stmt | TestBreak.java:12:9:12:9 | x | +| TestBreak.java:12:5:12:15 | if (...) | TestBreak.java:12:9:12:9 | x | | TestBreak.java:12:9:12:9 | x | TestBreak.java:12:14:12:14 | 1 | -| TestBreak.java:12:9:12:14 | ... == ... | TestBreak.java:13:5:15:5 | stmt | -| TestBreak.java:12:9:12:14 | ... == ... | TestBreak.java:16:5:27:5 | stmt | +| TestBreak.java:12:9:12:14 | ... == ... | TestBreak.java:13:5:15:5 | { ... } | +| TestBreak.java:12:9:12:14 | ... == ... | TestBreak.java:16:5:27:5 | { ... } | | TestBreak.java:12:14:12:14 | 1 | TestBreak.java:12:9:12:14 | ... == ... | -| TestBreak.java:13:5:15:5 | stmt | TestBreak.java:14:6:14:11 | stmt | -| TestBreak.java:14:6:14:11 | stmt | TestBreak.java:29:3:29:13 | stmt | -| TestBreak.java:16:5:27:5 | stmt | TestBreak.java:17:6:17:30 | stmt | -| TestBreak.java:17:6:17:30 | stmt | TestBreak.java:17:27:17:28 | 20 | -| TestBreak.java:17:15:17:15 | q | TestBreak.java:18:6:26:6 | stmt | -| TestBreak.java:17:19:17:29 | new int[] | TestBreak.java:9:4:28:4 | stmt | +| TestBreak.java:13:5:15:5 | { ... } | TestBreak.java:14:6:14:11 | break | +| TestBreak.java:14:6:14:11 | break | TestBreak.java:29:3:29:13 | local variable declaration | +| TestBreak.java:16:5:27:5 | { ... } | TestBreak.java:17:6:17:30 | for (... : ...) | +| TestBreak.java:17:6:17:30 | for (... : ...) | TestBreak.java:17:27:17:28 | 20 | +| TestBreak.java:17:15:17:15 | q | TestBreak.java:18:6:26:6 | { ... } | +| TestBreak.java:17:19:17:29 | new int[] | TestBreak.java:9:4:28:4 | { ... } | | TestBreak.java:17:19:17:29 | new int[] | TestBreak.java:17:15:17:15 | q | | TestBreak.java:17:27:17:28 | 20 | TestBreak.java:17:19:17:29 | new int[] | -| TestBreak.java:18:6:26:6 | stmt | TestBreak.java:19:7:19:17 | stmt | -| TestBreak.java:19:7:19:17 | stmt | TestBreak.java:19:11:19:11 | q | +| TestBreak.java:18:6:26:6 | { ... } | TestBreak.java:19:7:19:17 | if (...) | +| TestBreak.java:19:7:19:17 | if (...) | TestBreak.java:19:11:19:11 | q | | TestBreak.java:19:11:19:11 | q | TestBreak.java:19:16:19:16 | 1 | -| TestBreak.java:19:11:19:16 | ... == ... | TestBreak.java:20:7:22:7 | stmt | -| TestBreak.java:19:11:19:16 | ... == ... | TestBreak.java:23:7:25:7 | stmt | +| TestBreak.java:19:11:19:16 | ... == ... | TestBreak.java:20:7:22:7 | { ... } | +| TestBreak.java:19:11:19:16 | ... == ... | TestBreak.java:23:7:25:7 | { ... } | | TestBreak.java:19:16:19:16 | 1 | TestBreak.java:19:11:19:16 | ... == ... | -| TestBreak.java:20:7:22:7 | stmt | TestBreak.java:21:8:21:13 | stmt | -| TestBreak.java:21:8:21:13 | stmt | TestBreak.java:9:4:28:4 | stmt | -| TestBreak.java:23:7:25:7 | stmt | TestBreak.java:24:8:24:15 | stmt | -| TestBreak.java:24:8:24:15 | stmt | TestBreak.java:29:3:29:13 | stmt | -| TestBreak.java:29:3:29:13 | stmt | TestBreak.java:29:11:29:12 | 12 | -| TestBreak.java:29:7:29:12 | y | TestBreak.java:30:3:30:14 | stmt | +| TestBreak.java:20:7:22:7 | { ... } | TestBreak.java:21:8:21:13 | break | +| TestBreak.java:21:8:21:13 | break | TestBreak.java:9:4:28:4 | { ... } | +| TestBreak.java:23:7:25:7 | { ... } | TestBreak.java:24:8:24:15 | break | +| TestBreak.java:24:8:24:15 | break | TestBreak.java:29:3:29:13 | local variable declaration | +| TestBreak.java:29:3:29:13 | local variable declaration | TestBreak.java:29:11:29:12 | 12 | +| TestBreak.java:29:7:29:12 | y | TestBreak.java:30:3:30:14 | while (...) | | TestBreak.java:29:11:29:12 | 12 | TestBreak.java:29:7:29:12 | y | -| TestBreak.java:30:3:30:14 | stmt | TestBreak.java:30:10:30:13 | true | -| TestBreak.java:30:10:30:13 | true | TestBreak.java:31:3:47:3 | stmt | -| TestBreak.java:31:3:47:3 | stmt | TestBreak.java:32:4:32:14 | stmt | -| TestBreak.java:32:4:32:14 | stmt | TestBreak.java:32:8:32:8 | y | +| TestBreak.java:30:3:30:14 | while (...) | TestBreak.java:30:10:30:13 | true | +| TestBreak.java:30:10:30:13 | true | TestBreak.java:31:3:47:3 | { ... } | +| TestBreak.java:31:3:47:3 | { ... } | TestBreak.java:32:4:32:14 | if (...) | +| TestBreak.java:32:4:32:14 | if (...) | TestBreak.java:32:8:32:8 | y | | TestBreak.java:32:8:32:8 | y | TestBreak.java:32:13:32:13 | 1 | -| TestBreak.java:32:8:32:13 | ... == ... | TestBreak.java:33:4:35:4 | stmt | -| TestBreak.java:32:8:32:13 | ... == ... | TestBreak.java:36:4:46:4 | stmt | +| TestBreak.java:32:8:32:13 | ... == ... | TestBreak.java:33:4:35:4 | { ... } | +| TestBreak.java:32:8:32:13 | ... == ... | TestBreak.java:36:4:46:4 | { ... } | | TestBreak.java:32:13:32:13 | 1 | TestBreak.java:32:8:32:13 | ... == ... | -| TestBreak.java:33:4:35:4 | stmt | TestBreak.java:34:5:34:10 | stmt | -| TestBreak.java:34:5:34:10 | stmt | TestBreak.java:48:3:48:9 | stmt | -| TestBreak.java:36:4:46:4 | stmt | TestBreak.java:37:5:44:21 | stmt | -| TestBreak.java:37:5:44:21 | stmt | TestBreak.java:38:5:44:5 | stmt | -| TestBreak.java:38:5:44:5 | stmt | TestBreak.java:39:6:39:16 | stmt | -| TestBreak.java:39:6:39:16 | stmt | TestBreak.java:39:10:39:10 | y | +| TestBreak.java:33:4:35:4 | { ... } | TestBreak.java:34:5:34:10 | break | +| TestBreak.java:34:5:34:10 | break | TestBreak.java:48:3:48:9 | ...; | +| TestBreak.java:36:4:46:4 | { ... } | TestBreak.java:37:5:44:21 | do ... while (...) | +| TestBreak.java:37:5:44:21 | do ... while (...) | TestBreak.java:38:5:44:5 | { ... } | +| TestBreak.java:38:5:44:5 | { ... } | TestBreak.java:39:6:39:16 | if (...) | +| TestBreak.java:39:6:39:16 | if (...) | TestBreak.java:39:10:39:10 | y | | TestBreak.java:39:10:39:10 | y | TestBreak.java:39:15:39:15 | 2 | -| TestBreak.java:39:10:39:15 | ... == ... | TestBreak.java:40:6:42:6 | stmt | -| TestBreak.java:39:10:39:15 | ... == ... | TestBreak.java:43:6:43:15 | stmt | +| TestBreak.java:39:10:39:15 | ... == ... | TestBreak.java:40:6:42:6 | { ... } | +| TestBreak.java:39:10:39:15 | ... == ... | TestBreak.java:43:6:43:15 | ...; | | TestBreak.java:39:15:39:15 | 2 | TestBreak.java:39:10:39:15 | ... == ... | -| TestBreak.java:40:6:42:6 | stmt | TestBreak.java:41:7:41:12 | stmt | -| TestBreak.java:41:7:41:12 | stmt | TestBreak.java:45:5:45:11 | stmt | +| TestBreak.java:40:6:42:6 | { ... } | TestBreak.java:41:7:41:12 | break | +| TestBreak.java:41:7:41:12 | break | TestBreak.java:45:5:45:11 | ...; | | TestBreak.java:43:6:43:14 | ...=... | TestBreak.java:44:14:44:14 | y | -| TestBreak.java:43:6:43:15 | stmt | TestBreak.java:43:10:43:10 | y | +| TestBreak.java:43:6:43:15 | ...; | TestBreak.java:43:10:43:10 | y | | TestBreak.java:43:10:43:10 | y | TestBreak.java:43:14:43:14 | 2 | | TestBreak.java:43:10:43:14 | ... + ... | TestBreak.java:43:6:43:14 | ...=... | | TestBreak.java:43:14:43:14 | 2 | TestBreak.java:43:10:43:14 | ... + ... | | TestBreak.java:44:14:44:14 | y | TestBreak.java:44:19:44:19 | 1 | -| TestBreak.java:44:14:44:19 | ... == ... | TestBreak.java:38:5:44:5 | stmt | -| TestBreak.java:44:14:44:19 | ... == ... | TestBreak.java:45:5:45:11 | stmt | +| TestBreak.java:44:14:44:19 | ... == ... | TestBreak.java:38:5:44:5 | { ... } | +| TestBreak.java:44:14:44:19 | ... == ... | TestBreak.java:45:5:45:11 | ...; | | TestBreak.java:44:19:44:19 | 1 | TestBreak.java:44:14:44:19 | ... == ... | | TestBreak.java:45:5:45:10 | ...=... | TestBreak.java:30:10:30:13 | true | -| TestBreak.java:45:5:45:11 | stmt | TestBreak.java:45:9:45:10 | 12 | +| TestBreak.java:45:5:45:11 | ...; | TestBreak.java:45:9:45:10 | 12 | | TestBreak.java:45:9:45:10 | 12 | TestBreak.java:45:5:45:10 | ...=... | -| TestBreak.java:48:3:48:8 | ...=... | TestBreak.java:51:3:51:12 | stmt | -| TestBreak.java:48:3:48:9 | stmt | TestBreak.java:48:7:48:8 | 13 | +| TestBreak.java:48:3:48:8 | ...=... | TestBreak.java:51:3:51:12 | local variable declaration | +| TestBreak.java:48:3:48:9 | ...; | TestBreak.java:48:7:48:8 | 13 | | TestBreak.java:48:7:48:8 | 13 | TestBreak.java:48:3:48:8 | ...=... | -| TestBreak.java:51:3:51:12 | stmt | TestBreak.java:51:10:51:11 | 12 | -| TestBreak.java:51:7:51:11 | x | TestBreak.java:52:3:52:12 | stmt | +| TestBreak.java:51:3:51:12 | local variable declaration | TestBreak.java:51:10:51:11 | 12 | +| TestBreak.java:51:7:51:11 | x | TestBreak.java:52:3:52:12 | switch (...) | | TestBreak.java:51:10:51:11 | 12 | TestBreak.java:51:7:51:11 | x | -| TestBreak.java:52:3:52:12 | stmt | TestBreak.java:52:11:52:11 | x | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:54:3:54:9 | stmt | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:57:3:57:9 | stmt | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:61:3:61:9 | stmt | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:62:3:62:9 | stmt | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:66:3:66:9 | stmt | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:67:3:67:9 | stmt | -| TestBreak.java:52:11:52:11 | x | TestBreak.java:70:3:70:10 | stmt | -| TestBreak.java:54:3:54:9 | stmt | TestBreak.java:55:4:55:13 | stmt | -| TestBreak.java:55:4:55:12 | ...=... | TestBreak.java:56:4:56:13 | stmt | -| TestBreak.java:55:4:55:13 | stmt | TestBreak.java:55:8:55:8 | x | +| TestBreak.java:52:3:52:12 | switch (...) | TestBreak.java:52:11:52:11 | x | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:54:3:54:9 | case ... | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:57:3:57:9 | case ... | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:61:3:61:9 | case ... | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:62:3:62:9 | case ... | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:66:3:66:9 | case ... | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:67:3:67:9 | case ... | +| TestBreak.java:52:11:52:11 | x | TestBreak.java:70:3:70:10 | default | +| TestBreak.java:54:3:54:9 | case ... | TestBreak.java:55:4:55:13 | ...; | +| TestBreak.java:55:4:55:12 | ...=... | TestBreak.java:56:4:56:13 | ...; | +| TestBreak.java:55:4:55:13 | ...; | TestBreak.java:55:8:55:8 | x | | TestBreak.java:55:8:55:8 | x | TestBreak.java:55:12:55:12 | 1 | | TestBreak.java:55:8:55:12 | ... + ... | TestBreak.java:55:4:55:12 | ...=... | | TestBreak.java:55:12:55:12 | 1 | TestBreak.java:55:8:55:12 | ... + ... | -| TestBreak.java:56:4:56:12 | ...=... | TestBreak.java:57:3:57:9 | stmt | -| TestBreak.java:56:4:56:13 | stmt | TestBreak.java:56:8:56:8 | y | +| TestBreak.java:56:4:56:12 | ...=... | TestBreak.java:57:3:57:9 | case ... | +| TestBreak.java:56:4:56:13 | ...; | TestBreak.java:56:8:56:8 | y | | TestBreak.java:56:8:56:8 | y | TestBreak.java:56:12:56:12 | 1 | | TestBreak.java:56:8:56:12 | ... + ... | TestBreak.java:56:4:56:12 | ...=... | | TestBreak.java:56:12:56:12 | 1 | TestBreak.java:56:8:56:12 | ... + ... | -| TestBreak.java:57:3:57:9 | stmt | TestBreak.java:58:4:58:13 | stmt | -| TestBreak.java:58:4:58:12 | ...=... | TestBreak.java:59:4:59:13 | stmt | -| TestBreak.java:58:4:58:13 | stmt | TestBreak.java:58:8:58:8 | x | +| TestBreak.java:57:3:57:9 | case ... | TestBreak.java:58:4:58:13 | ...; | +| TestBreak.java:58:4:58:12 | ...=... | TestBreak.java:59:4:59:13 | ...; | +| TestBreak.java:58:4:58:13 | ...; | TestBreak.java:58:8:58:8 | x | | TestBreak.java:58:8:58:8 | x | TestBreak.java:58:12:58:12 | 2 | | TestBreak.java:58:8:58:12 | ... + ... | TestBreak.java:58:4:58:12 | ...=... | | TestBreak.java:58:12:58:12 | 2 | TestBreak.java:58:8:58:12 | ... + ... | -| TestBreak.java:59:4:59:12 | ...=... | TestBreak.java:60:4:60:9 | stmt | -| TestBreak.java:59:4:59:13 | stmt | TestBreak.java:59:8:59:8 | y | +| TestBreak.java:59:4:59:12 | ...=... | TestBreak.java:60:4:60:9 | break | +| TestBreak.java:59:4:59:13 | ...; | TestBreak.java:59:8:59:8 | y | | TestBreak.java:59:8:59:8 | y | TestBreak.java:59:12:59:12 | 2 | | TestBreak.java:59:8:59:12 | ... + ... | TestBreak.java:59:4:59:12 | ...=... | | TestBreak.java:59:12:59:12 | 2 | TestBreak.java:59:8:59:12 | ... + ... | -| TestBreak.java:60:4:60:9 | stmt | TestBreak.java:76:3:76:11 | stmt | -| TestBreak.java:61:3:61:9 | stmt | TestBreak.java:62:3:62:9 | stmt | -| TestBreak.java:62:3:62:9 | stmt | TestBreak.java:63:4:63:13 | stmt | -| TestBreak.java:63:4:63:12 | ...=... | TestBreak.java:64:4:64:13 | stmt | -| TestBreak.java:63:4:63:13 | stmt | TestBreak.java:63:8:63:8 | x | +| TestBreak.java:60:4:60:9 | break | TestBreak.java:76:3:76:11 | switch (...) | +| TestBreak.java:61:3:61:9 | case ... | TestBreak.java:62:3:62:9 | case ... | +| TestBreak.java:62:3:62:9 | case ... | TestBreak.java:63:4:63:13 | ...; | +| TestBreak.java:63:4:63:12 | ...=... | TestBreak.java:64:4:64:13 | ...; | +| TestBreak.java:63:4:63:13 | ...; | TestBreak.java:63:8:63:8 | x | | TestBreak.java:63:8:63:8 | x | TestBreak.java:63:12:63:12 | 3 | | TestBreak.java:63:8:63:12 | ... + ... | TestBreak.java:63:4:63:12 | ...=... | | TestBreak.java:63:12:63:12 | 3 | TestBreak.java:63:8:63:12 | ... + ... | -| TestBreak.java:64:4:64:12 | ...=... | TestBreak.java:65:4:65:9 | stmt | -| TestBreak.java:64:4:64:13 | stmt | TestBreak.java:64:8:64:8 | y | +| TestBreak.java:64:4:64:12 | ...=... | TestBreak.java:65:4:65:9 | break | +| TestBreak.java:64:4:64:13 | ...; | TestBreak.java:64:8:64:8 | y | | TestBreak.java:64:8:64:8 | y | TestBreak.java:64:12:64:12 | 4 | | TestBreak.java:64:8:64:12 | ... + ... | TestBreak.java:64:4:64:12 | ...=... | | TestBreak.java:64:12:64:12 | 4 | TestBreak.java:64:8:64:12 | ... + ... | -| TestBreak.java:65:4:65:9 | stmt | TestBreak.java:76:3:76:11 | stmt | -| TestBreak.java:66:3:66:9 | stmt | TestBreak.java:67:3:67:9 | stmt | -| TestBreak.java:67:3:67:9 | stmt | TestBreak.java:68:4:68:13 | stmt | -| TestBreak.java:68:4:68:12 | ...=... | TestBreak.java:69:4:69:13 | stmt | -| TestBreak.java:68:4:68:13 | stmt | TestBreak.java:68:8:68:8 | x | +| TestBreak.java:65:4:65:9 | break | TestBreak.java:76:3:76:11 | switch (...) | +| TestBreak.java:66:3:66:9 | case ... | TestBreak.java:67:3:67:9 | case ... | +| TestBreak.java:67:3:67:9 | case ... | TestBreak.java:68:4:68:13 | ...; | +| TestBreak.java:68:4:68:12 | ...=... | TestBreak.java:69:4:69:13 | ...; | +| TestBreak.java:68:4:68:13 | ...; | TestBreak.java:68:8:68:8 | x | | TestBreak.java:68:8:68:8 | x | TestBreak.java:68:12:68:12 | 5 | | TestBreak.java:68:8:68:12 | ... + ... | TestBreak.java:68:4:68:12 | ...=... | | TestBreak.java:68:12:68:12 | 5 | TestBreak.java:68:8:68:12 | ... + ... | -| TestBreak.java:69:4:69:12 | ...=... | TestBreak.java:70:3:70:10 | stmt | -| TestBreak.java:69:4:69:13 | stmt | TestBreak.java:69:8:69:8 | y | +| TestBreak.java:69:4:69:12 | ...=... | TestBreak.java:70:3:70:10 | default | +| TestBreak.java:69:4:69:13 | ...; | TestBreak.java:69:8:69:8 | y | | TestBreak.java:69:8:69:8 | y | TestBreak.java:69:12:69:12 | 6 | | TestBreak.java:69:8:69:12 | ... + ... | TestBreak.java:69:4:69:12 | ...=... | | TestBreak.java:69:12:69:12 | 6 | TestBreak.java:69:8:69:12 | ... + ... | -| TestBreak.java:70:3:70:10 | stmt | TestBreak.java:71:4:71:9 | stmt | -| TestBreak.java:71:4:71:8 | ...=... | TestBreak.java:72:4:72:9 | stmt | -| TestBreak.java:71:4:71:9 | stmt | TestBreak.java:71:8:71:8 | y | +| TestBreak.java:70:3:70:10 | default | TestBreak.java:71:4:71:9 | ...; | +| TestBreak.java:71:4:71:8 | ...=... | TestBreak.java:72:4:72:9 | ...; | +| TestBreak.java:71:4:71:9 | ...; | TestBreak.java:71:8:71:8 | y | | TestBreak.java:71:8:71:8 | y | TestBreak.java:71:4:71:8 | ...=... | -| TestBreak.java:72:4:72:8 | ...=... | TestBreak.java:76:3:76:11 | stmt | -| TestBreak.java:72:4:72:9 | stmt | TestBreak.java:72:8:72:8 | x | +| TestBreak.java:72:4:72:8 | ...=... | TestBreak.java:76:3:76:11 | switch (...) | +| TestBreak.java:72:4:72:9 | ...; | TestBreak.java:72:8:72:8 | x | | TestBreak.java:72:8:72:8 | x | TestBreak.java:72:4:72:8 | ...=... | -| TestBreak.java:76:3:76:11 | stmt | TestBreak.java:76:10:76:10 | x | +| TestBreak.java:76:3:76:11 | switch (...) | TestBreak.java:76:10:76:10 | x | | TestBreak.java:76:10:76:10 | x | TestBreak.java:4:14:4:14 | f | -| TestBreak.java:76:10:76:10 | x | TestBreak.java:78:3:78:9 | stmt | -| TestBreak.java:76:10:76:10 | x | TestBreak.java:81:3:81:9 | stmt | -| TestBreak.java:78:3:78:9 | stmt | TestBreak.java:79:4:79:9 | stmt | -| TestBreak.java:79:4:79:8 | ...=... | TestBreak.java:80:4:80:9 | stmt | -| TestBreak.java:79:4:79:9 | stmt | TestBreak.java:79:8:79:8 | 1 | +| TestBreak.java:76:10:76:10 | x | TestBreak.java:78:3:78:9 | case ... | +| TestBreak.java:76:10:76:10 | x | TestBreak.java:81:3:81:9 | case ... | +| TestBreak.java:78:3:78:9 | case ... | TestBreak.java:79:4:79:9 | ...; | +| TestBreak.java:79:4:79:8 | ...=... | TestBreak.java:80:4:80:9 | break | +| TestBreak.java:79:4:79:9 | ...; | TestBreak.java:79:8:79:8 | 1 | | TestBreak.java:79:8:79:8 | 1 | TestBreak.java:79:4:79:8 | ...=... | -| TestBreak.java:80:4:80:9 | stmt | TestBreak.java:4:14:4:14 | f | -| TestBreak.java:81:3:81:9 | stmt | TestBreak.java:82:4:82:9 | stmt | -| TestBreak.java:82:4:82:8 | ...=... | TestBreak.java:83:4:83:9 | stmt | -| TestBreak.java:82:4:82:9 | stmt | TestBreak.java:82:8:82:8 | 2 | +| TestBreak.java:80:4:80:9 | break | TestBreak.java:4:14:4:14 | f | +| TestBreak.java:81:3:81:9 | case ... | TestBreak.java:82:4:82:9 | ...; | +| TestBreak.java:82:4:82:8 | ...=... | TestBreak.java:83:4:83:9 | break | +| TestBreak.java:82:4:82:9 | ...; | TestBreak.java:82:8:82:8 | 2 | | TestBreak.java:82:8:82:8 | 2 | TestBreak.java:82:4:82:8 | ...=... | -| TestBreak.java:83:4:83:9 | stmt | TestBreak.java:4:14:4:14 | f | +| TestBreak.java:83:4:83:9 | break | TestBreak.java:4:14:4:14 | f | diff --git a/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected index 046cece6f7f..a5da44bd900 100644 --- a/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected @@ -1,10 +1,10 @@ -| TestContinue.java:8:20:8:25 | ... < ... | TestContinue.java:30:3:30:13 | stmt | -| TestContinue.java:12:9:12:14 | ... == ... | TestContinue.java:16:5:28:5 | stmt | -| TestContinue.java:19:11:19:16 | ... == ... | TestContinue.java:22:14:22:24 | stmt | -| TestContinue.java:22:18:22:23 | ... == ... | TestContinue.java:26:7:26:13 | stmt | -| TestContinue.java:31:10:31:16 | ... != ... | TestContinue.java:50:3:50:9 | stmt | -| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:37:4:47:4 | stmt | -| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:44:6:44:15 | stmt | -| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:46:5:46:11 | stmt | +| TestContinue.java:8:20:8:25 | ... < ... | TestContinue.java:30:3:30:13 | local variable declaration | +| TestContinue.java:12:9:12:14 | ... == ... | TestContinue.java:16:5:28:5 | { ... } | +| TestContinue.java:19:11:19:16 | ... == ... | TestContinue.java:22:14:22:24 | if (...) | +| TestContinue.java:22:18:22:23 | ... == ... | TestContinue.java:26:7:26:13 | ...; | +| TestContinue.java:31:10:31:16 | ... != ... | TestContinue.java:50:3:50:9 | ...; | +| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:37:4:47:4 | { ... } | +| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:44:6:44:15 | ...; | +| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:46:5:46:11 | ...; | | TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:4:14:4:14 | f | -| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | stmt | +| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | break | diff --git a/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected b/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected index c12e88e7080..50ce7f6a524 100644 --- a/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected @@ -1,110 +1,110 @@ -| TestContinue.java:3:14:3:25 | stmt | TestContinue.java:3:14:3:25 | super(...) | | TestContinue.java:3:14:3:25 | super(...) | TestContinue.java:3:14:3:25 | TestContinue | -| TestContinue.java:5:2:58:2 | stmt | TestContinue.java:7:3:8:27 | stmt | -| TestContinue.java:7:3:8:27 | stmt | TestContinue.java:8:4:8:27 | stmt | -| TestContinue.java:8:4:8:27 | stmt | TestContinue.java:8:17:8:17 | 0 | +| TestContinue.java:3:14:3:25 | { ... } | TestContinue.java:3:14:3:25 | super(...) | +| TestContinue.java:5:2:58:2 | { ... } | TestContinue.java:7:3:8:27 | labeled statement | +| TestContinue.java:7:3:8:27 | labeled statement | TestContinue.java:8:4:8:27 | for (...) | +| TestContinue.java:8:4:8:27 | for (...) | TestContinue.java:8:17:8:17 | 0 | | TestContinue.java:8:13:8:17 | p | TestContinue.java:8:20:8:20 | p | | TestContinue.java:8:17:8:17 | 0 | TestContinue.java:8:13:8:17 | p | | TestContinue.java:8:20:8:20 | p | TestContinue.java:8:24:8:25 | 10 | -| TestContinue.java:8:20:8:25 | ... < ... | TestContinue.java:9:4:29:4 | stmt | -| TestContinue.java:8:20:8:25 | ... < ... | TestContinue.java:30:3:30:13 | stmt | +| TestContinue.java:8:20:8:25 | ... < ... | TestContinue.java:9:4:29:4 | { ... } | +| TestContinue.java:8:20:8:25 | ... < ... | TestContinue.java:30:3:30:13 | local variable declaration | | TestContinue.java:8:24:8:25 | 10 | TestContinue.java:8:20:8:25 | ... < ... | -| TestContinue.java:9:4:29:4 | stmt | TestContinue.java:10:5:10:14 | stmt | -| TestContinue.java:10:5:10:14 | stmt | TestContinue.java:10:13:10:13 | 1 | -| TestContinue.java:10:9:10:13 | x | TestContinue.java:11:5:11:14 | stmt | +| TestContinue.java:9:4:29:4 | { ... } | TestContinue.java:10:5:10:14 | local variable declaration | +| TestContinue.java:10:5:10:14 | local variable declaration | TestContinue.java:10:13:10:13 | 1 | +| TestContinue.java:10:9:10:13 | x | TestContinue.java:11:5:11:14 | ...; | | TestContinue.java:10:13:10:13 | 1 | TestContinue.java:10:9:10:13 | x | -| TestContinue.java:11:5:11:13 | ...=... | TestContinue.java:12:5:12:15 | stmt | -| TestContinue.java:11:5:11:14 | stmt | TestContinue.java:11:9:11:9 | x | +| TestContinue.java:11:5:11:13 | ...=... | TestContinue.java:12:5:12:15 | if (...) | +| TestContinue.java:11:5:11:14 | ...; | TestContinue.java:11:9:11:9 | x | | TestContinue.java:11:9:11:9 | x | TestContinue.java:11:13:11:13 | 1 | | TestContinue.java:11:9:11:13 | ... + ... | TestContinue.java:11:5:11:13 | ...=... | | TestContinue.java:11:13:11:13 | 1 | TestContinue.java:11:9:11:13 | ... + ... | -| TestContinue.java:12:5:12:15 | stmt | TestContinue.java:12:9:12:9 | x | +| TestContinue.java:12:5:12:15 | if (...) | TestContinue.java:12:9:12:9 | x | | TestContinue.java:12:9:12:9 | x | TestContinue.java:12:14:12:14 | 1 | -| TestContinue.java:12:9:12:14 | ... == ... | TestContinue.java:13:5:15:5 | stmt | -| TestContinue.java:12:9:12:14 | ... == ... | TestContinue.java:16:5:28:5 | stmt | +| TestContinue.java:12:9:12:14 | ... == ... | TestContinue.java:13:5:15:5 | { ... } | +| TestContinue.java:12:9:12:14 | ... == ... | TestContinue.java:16:5:28:5 | { ... } | | TestContinue.java:12:14:12:14 | 1 | TestContinue.java:12:9:12:14 | ... == ... | -| TestContinue.java:13:5:15:5 | stmt | TestContinue.java:14:6:14:14 | stmt | -| TestContinue.java:14:6:14:14 | stmt | TestContinue.java:8:20:8:20 | p | -| TestContinue.java:16:5:28:5 | stmt | TestContinue.java:17:6:17:30 | stmt | -| TestContinue.java:17:6:17:30 | stmt | TestContinue.java:17:27:17:28 | 20 | -| TestContinue.java:17:15:17:15 | q | TestContinue.java:18:6:27:6 | stmt | +| TestContinue.java:13:5:15:5 | { ... } | TestContinue.java:14:6:14:14 | continue | +| TestContinue.java:14:6:14:14 | continue | TestContinue.java:8:20:8:20 | p | +| TestContinue.java:16:5:28:5 | { ... } | TestContinue.java:17:6:17:30 | for (... : ...) | +| TestContinue.java:17:6:17:30 | for (... : ...) | TestContinue.java:17:27:17:28 | 20 | +| TestContinue.java:17:15:17:15 | q | TestContinue.java:18:6:27:6 | { ... } | | TestContinue.java:17:19:17:29 | new int[] | TestContinue.java:8:20:8:20 | p | | TestContinue.java:17:19:17:29 | new int[] | TestContinue.java:17:15:17:15 | q | | TestContinue.java:17:27:17:28 | 20 | TestContinue.java:17:19:17:29 | new int[] | -| TestContinue.java:18:6:27:6 | stmt | TestContinue.java:19:7:19:17 | stmt | -| TestContinue.java:19:7:19:17 | stmt | TestContinue.java:19:11:19:11 | q | +| TestContinue.java:18:6:27:6 | { ... } | TestContinue.java:19:7:19:17 | if (...) | +| TestContinue.java:19:7:19:17 | if (...) | TestContinue.java:19:11:19:11 | q | | TestContinue.java:19:11:19:11 | q | TestContinue.java:19:16:19:16 | 1 | -| TestContinue.java:19:11:19:16 | ... == ... | TestContinue.java:20:7:22:7 | stmt | -| TestContinue.java:19:11:19:16 | ... == ... | TestContinue.java:22:14:22:24 | stmt | +| TestContinue.java:19:11:19:16 | ... == ... | TestContinue.java:20:7:22:7 | { ... } | +| TestContinue.java:19:11:19:16 | ... == ... | TestContinue.java:22:14:22:24 | if (...) | | TestContinue.java:19:16:19:16 | 1 | TestContinue.java:19:11:19:16 | ... == ... | -| TestContinue.java:20:7:22:7 | stmt | TestContinue.java:21:8:21:16 | stmt | -| TestContinue.java:21:8:21:16 | stmt | TestContinue.java:8:20:8:20 | p | -| TestContinue.java:21:8:21:16 | stmt | TestContinue.java:17:15:17:15 | q | -| TestContinue.java:22:14:22:24 | stmt | TestContinue.java:22:18:22:18 | q | +| TestContinue.java:20:7:22:7 | { ... } | TestContinue.java:21:8:21:16 | continue | +| TestContinue.java:21:8:21:16 | continue | TestContinue.java:8:20:8:20 | p | +| TestContinue.java:21:8:21:16 | continue | TestContinue.java:17:15:17:15 | q | +| TestContinue.java:22:14:22:24 | if (...) | TestContinue.java:22:18:22:18 | q | | TestContinue.java:22:18:22:18 | q | TestContinue.java:22:23:22:23 | 2 | -| TestContinue.java:22:18:22:23 | ... == ... | TestContinue.java:23:7:25:7 | stmt | -| TestContinue.java:22:18:22:23 | ... == ... | TestContinue.java:26:7:26:13 | stmt | +| TestContinue.java:22:18:22:23 | ... == ... | TestContinue.java:23:7:25:7 | { ... } | +| TestContinue.java:22:18:22:23 | ... == ... | TestContinue.java:26:7:26:13 | ...; | | TestContinue.java:22:23:22:23 | 2 | TestContinue.java:22:18:22:23 | ... == ... | -| TestContinue.java:23:7:25:7 | stmt | TestContinue.java:24:8:24:18 | stmt | -| TestContinue.java:24:8:24:18 | stmt | TestContinue.java:8:20:8:20 | p | +| TestContinue.java:23:7:25:7 | { ... } | TestContinue.java:24:8:24:18 | continue | +| TestContinue.java:24:8:24:18 | continue | TestContinue.java:8:20:8:20 | p | | TestContinue.java:26:7:26:12 | ...=... | TestContinue.java:8:20:8:20 | p | | TestContinue.java:26:7:26:12 | ...=... | TestContinue.java:17:15:17:15 | q | -| TestContinue.java:26:7:26:13 | stmt | TestContinue.java:26:11:26:12 | 12 | +| TestContinue.java:26:7:26:13 | ...; | TestContinue.java:26:11:26:12 | 12 | | TestContinue.java:26:11:26:12 | 12 | TestContinue.java:26:7:26:12 | ...=... | -| TestContinue.java:30:3:30:13 | stmt | TestContinue.java:30:11:30:12 | 12 | -| TestContinue.java:30:7:30:12 | y | TestContinue.java:31:3:31:17 | stmt | +| TestContinue.java:30:3:30:13 | local variable declaration | TestContinue.java:30:11:30:12 | 12 | +| TestContinue.java:30:7:30:12 | y | TestContinue.java:31:3:31:17 | while (...) | | TestContinue.java:30:11:30:12 | 12 | TestContinue.java:30:7:30:12 | y | -| TestContinue.java:31:3:31:17 | stmt | TestContinue.java:31:10:31:10 | y | +| TestContinue.java:31:3:31:17 | while (...) | TestContinue.java:31:10:31:10 | y | | TestContinue.java:31:10:31:10 | y | TestContinue.java:31:15:31:16 | 13 | -| TestContinue.java:31:10:31:16 | ... != ... | TestContinue.java:32:3:49:3 | stmt | -| TestContinue.java:31:10:31:16 | ... != ... | TestContinue.java:50:3:50:9 | stmt | +| TestContinue.java:31:10:31:16 | ... != ... | TestContinue.java:32:3:49:3 | { ... } | +| TestContinue.java:31:10:31:16 | ... != ... | TestContinue.java:50:3:50:9 | ...; | | TestContinue.java:31:15:31:16 | 13 | TestContinue.java:31:10:31:16 | ... != ... | -| TestContinue.java:32:3:49:3 | stmt | TestContinue.java:33:4:33:14 | stmt | -| TestContinue.java:33:4:33:14 | stmt | TestContinue.java:33:8:33:8 | y | +| TestContinue.java:32:3:49:3 | { ... } | TestContinue.java:33:4:33:14 | if (...) | +| TestContinue.java:33:4:33:14 | if (...) | TestContinue.java:33:8:33:8 | y | | TestContinue.java:33:8:33:8 | y | TestContinue.java:33:13:33:13 | 1 | -| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:34:4:36:4 | stmt | -| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:37:4:47:4 | stmt | +| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:34:4:36:4 | { ... } | +| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:37:4:47:4 | { ... } | | TestContinue.java:33:13:33:13 | 1 | TestContinue.java:33:8:33:13 | ... == ... | -| TestContinue.java:34:4:36:4 | stmt | TestContinue.java:35:5:35:13 | stmt | -| TestContinue.java:35:5:35:13 | stmt | TestContinue.java:31:10:31:10 | y | -| TestContinue.java:37:4:47:4 | stmt | TestContinue.java:38:5:45:21 | stmt | -| TestContinue.java:38:5:45:21 | stmt | TestContinue.java:39:5:45:5 | stmt | -| TestContinue.java:39:5:45:5 | stmt | TestContinue.java:40:6:40:16 | stmt | -| TestContinue.java:40:6:40:16 | stmt | TestContinue.java:40:10:40:10 | y | +| TestContinue.java:34:4:36:4 | { ... } | TestContinue.java:35:5:35:13 | continue | +| TestContinue.java:35:5:35:13 | continue | TestContinue.java:31:10:31:10 | y | +| TestContinue.java:37:4:47:4 | { ... } | TestContinue.java:38:5:45:21 | do ... while (...) | +| TestContinue.java:38:5:45:21 | do ... while (...) | TestContinue.java:39:5:45:5 | { ... } | +| TestContinue.java:39:5:45:5 | { ... } | TestContinue.java:40:6:40:16 | if (...) | +| TestContinue.java:40:6:40:16 | if (...) | TestContinue.java:40:10:40:10 | y | | TestContinue.java:40:10:40:10 | y | TestContinue.java:40:15:40:15 | 2 | -| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:41:6:43:6 | stmt | -| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:44:6:44:15 | stmt | +| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:41:6:43:6 | { ... } | +| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:44:6:44:15 | ...; | | TestContinue.java:40:15:40:15 | 2 | TestContinue.java:40:10:40:15 | ... == ... | -| TestContinue.java:41:6:43:6 | stmt | TestContinue.java:42:7:42:15 | stmt | -| TestContinue.java:42:7:42:15 | stmt | TestContinue.java:45:14:45:14 | y | +| TestContinue.java:41:6:43:6 | { ... } | TestContinue.java:42:7:42:15 | continue | +| TestContinue.java:42:7:42:15 | continue | TestContinue.java:45:14:45:14 | y | | TestContinue.java:44:6:44:14 | ...=... | TestContinue.java:45:14:45:14 | y | -| TestContinue.java:44:6:44:15 | stmt | TestContinue.java:44:10:44:10 | y | +| TestContinue.java:44:6:44:15 | ...; | TestContinue.java:44:10:44:10 | y | | TestContinue.java:44:10:44:10 | y | TestContinue.java:44:14:44:14 | 2 | | TestContinue.java:44:10:44:14 | ... + ... | TestContinue.java:44:6:44:14 | ...=... | | TestContinue.java:44:14:44:14 | 2 | TestContinue.java:44:10:44:14 | ... + ... | | TestContinue.java:45:14:45:14 | y | TestContinue.java:45:19:45:19 | 1 | -| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:39:5:45:5 | stmt | -| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:46:5:46:11 | stmt | +| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:39:5:45:5 | { ... } | +| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:46:5:46:11 | ...; | | TestContinue.java:45:19:45:19 | 1 | TestContinue.java:45:14:45:19 | ... == ... | -| TestContinue.java:46:5:46:10 | ...=... | TestContinue.java:48:4:48:10 | stmt | -| TestContinue.java:46:5:46:11 | stmt | TestContinue.java:46:9:46:10 | 12 | +| TestContinue.java:46:5:46:10 | ...=... | TestContinue.java:48:4:48:10 | ...; | +| TestContinue.java:46:5:46:11 | ...; | TestContinue.java:46:9:46:10 | 12 | | TestContinue.java:46:9:46:10 | 12 | TestContinue.java:46:5:46:10 | ...=... | | TestContinue.java:48:4:48:9 | ...=... | TestContinue.java:31:10:31:10 | y | -| TestContinue.java:48:4:48:10 | stmt | TestContinue.java:48:8:48:9 | 15 | +| TestContinue.java:48:4:48:10 | ...; | TestContinue.java:48:8:48:9 | 15 | | TestContinue.java:48:8:48:9 | 15 | TestContinue.java:48:4:48:9 | ...=... | -| TestContinue.java:50:3:50:8 | ...=... | TestContinue.java:51:3:51:17 | stmt | -| TestContinue.java:50:3:50:9 | stmt | TestContinue.java:50:7:50:8 | 13 | +| TestContinue.java:50:3:50:8 | ...=... | TestContinue.java:51:3:51:17 | while (...) | +| TestContinue.java:50:3:50:9 | ...; | TestContinue.java:50:7:50:8 | 13 | | TestContinue.java:50:7:50:8 | 13 | TestContinue.java:50:3:50:8 | ...=... | -| TestContinue.java:51:3:51:17 | stmt | TestContinue.java:51:10:51:10 | y | +| TestContinue.java:51:3:51:17 | while (...) | TestContinue.java:51:10:51:10 | y | | TestContinue.java:51:10:51:10 | y | TestContinue.java:51:15:51:16 | 12 | | TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:4:14:4:14 | f | -| TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:52:3:57:3 | stmt | +| TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:52:3:57:3 | { ... } | | TestContinue.java:51:15:51:16 | 12 | TestContinue.java:51:10:51:16 | ... != ... | -| TestContinue.java:52:3:57:3 | stmt | TestContinue.java:53:4:53:14 | stmt | -| TestContinue.java:53:4:53:14 | stmt | TestContinue.java:53:8:53:8 | y | +| TestContinue.java:52:3:57:3 | { ... } | TestContinue.java:53:4:53:14 | if (...) | +| TestContinue.java:53:4:53:14 | if (...) | TestContinue.java:53:8:53:8 | y | | TestContinue.java:53:8:53:8 | y | TestContinue.java:53:13:53:13 | 6 | -| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:54:5:54:13 | stmt | -| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | stmt | +| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:54:5:54:13 | continue | +| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | break | | TestContinue.java:53:13:53:13 | 6 | TestContinue.java:53:8:53:13 | ... != ... | -| TestContinue.java:54:5:54:13 | stmt | TestContinue.java:51:10:51:10 | y | -| TestContinue.java:56:5:56:10 | stmt | TestContinue.java:4:14:4:14 | f | +| TestContinue.java:54:5:54:13 | continue | TestContinue.java:51:10:51:10 | y | +| TestContinue.java:56:5:56:10 | break | TestContinue.java:4:14:4:14 | f | diff --git a/java/ql/test/library-tests/successors/TestDeclarations/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestDeclarations/FalseSuccessors.expected index b5b153e709a..c7e0cec8183 100644 --- a/java/ql/test/library-tests/successors/TestDeclarations/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestDeclarations/FalseSuccessors.expected @@ -1,3 +1,3 @@ -| TestDeclarations.java:10:8:10:14 | ... > ... | TestDeclarations.java:15:4:15:15 | stmt | -| TestDeclarations.java:15:8:15:14 | ... == ... | TestDeclarations.java:17:4:17:15 | stmt | +| TestDeclarations.java:10:8:10:14 | ... > ... | TestDeclarations.java:15:4:15:15 | if (...) | +| TestDeclarations.java:15:8:15:14 | ... == ... | TestDeclarations.java:17:4:17:15 | if (...) | | TestDeclarations.java:17:8:17:14 | ... == ... | TestDeclarations.java:7:9:7:12 | true | diff --git a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected index 73b0df6ab8a..9a05b5bb02d 100644 --- a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected @@ -1,54 +1,54 @@ -| TestDeclarations.java:1:7:1:22 | stmt | TestDeclarations.java:1:7:1:22 | super(...) | | TestDeclarations.java:1:7:1:22 | super(...) | TestDeclarations.java:1:7:1:22 | TestDeclarations | -| TestDeclarations.java:2:30:24:2 | stmt | TestDeclarations.java:4:3:4:11 | stmt | -| TestDeclarations.java:4:3:4:11 | stmt | TestDeclarations.java:4:7:4:7 | b | +| TestDeclarations.java:1:7:1:22 | { ... } | TestDeclarations.java:1:7:1:22 | super(...) | +| TestDeclarations.java:2:30:24:2 | { ... } | TestDeclarations.java:4:3:4:11 | local variable declaration | +| TestDeclarations.java:4:3:4:11 | local variable declaration | TestDeclarations.java:4:7:4:7 | b | | TestDeclarations.java:4:7:4:7 | b | TestDeclarations.java:4:10:4:10 | c | -| TestDeclarations.java:4:10:4:10 | c | TestDeclarations.java:5:3:5:8 | stmt | -| TestDeclarations.java:5:3:5:7 | ...=... | TestDeclarations.java:6:3:6:8 | stmt | -| TestDeclarations.java:5:3:5:8 | stmt | TestDeclarations.java:5:7:5:7 | 0 | +| TestDeclarations.java:4:10:4:10 | c | TestDeclarations.java:5:3:5:8 | ...; | +| TestDeclarations.java:5:3:5:7 | ...=... | TestDeclarations.java:6:3:6:8 | ...; | +| TestDeclarations.java:5:3:5:8 | ...; | TestDeclarations.java:5:7:5:7 | 0 | | TestDeclarations.java:5:7:5:7 | 0 | TestDeclarations.java:5:3:5:7 | ...=... | -| TestDeclarations.java:6:3:6:7 | ...=... | TestDeclarations.java:7:3:7:13 | stmt | -| TestDeclarations.java:6:3:6:8 | stmt | TestDeclarations.java:6:7:6:7 | 0 | +| TestDeclarations.java:6:3:6:7 | ...=... | TestDeclarations.java:7:3:7:13 | while (...) | +| TestDeclarations.java:6:3:6:8 | ...; | TestDeclarations.java:6:7:6:7 | 0 | | TestDeclarations.java:6:7:6:7 | 0 | TestDeclarations.java:6:3:6:7 | ...=... | -| TestDeclarations.java:7:3:7:13 | stmt | TestDeclarations.java:7:9:7:12 | true | -| TestDeclarations.java:7:9:7:12 | true | TestDeclarations.java:8:3:19:3 | stmt | -| TestDeclarations.java:8:3:19:3 | stmt | TestDeclarations.java:9:4:9:10 | stmt | -| TestDeclarations.java:9:4:9:9 | ...=... | TestDeclarations.java:10:4:10:15 | stmt | -| TestDeclarations.java:9:4:9:10 | stmt | TestDeclarations.java:9:8:9:9 | 10 | +| TestDeclarations.java:7:3:7:13 | while (...) | TestDeclarations.java:7:9:7:12 | true | +| TestDeclarations.java:7:9:7:12 | true | TestDeclarations.java:8:3:19:3 | { ... } | +| TestDeclarations.java:8:3:19:3 | { ... } | TestDeclarations.java:9:4:9:10 | ...; | +| TestDeclarations.java:9:4:9:9 | ...=... | TestDeclarations.java:10:4:10:15 | if (...) | +| TestDeclarations.java:9:4:9:10 | ...; | TestDeclarations.java:9:8:9:9 | 10 | | TestDeclarations.java:9:8:9:9 | 10 | TestDeclarations.java:9:4:9:9 | ...=... | -| TestDeclarations.java:10:4:10:15 | stmt | TestDeclarations.java:10:8:10:8 | a | +| TestDeclarations.java:10:4:10:15 | if (...) | TestDeclarations.java:10:8:10:8 | a | | TestDeclarations.java:10:8:10:8 | a | TestDeclarations.java:10:12:10:14 | 100 | -| TestDeclarations.java:10:8:10:14 | ... > ... | TestDeclarations.java:11:4:14:4 | stmt | -| TestDeclarations.java:10:8:10:14 | ... > ... | TestDeclarations.java:15:4:15:15 | stmt | +| TestDeclarations.java:10:8:10:14 | ... > ... | TestDeclarations.java:11:4:14:4 | { ... } | +| TestDeclarations.java:10:8:10:14 | ... > ... | TestDeclarations.java:15:4:15:15 | if (...) | | TestDeclarations.java:10:12:10:14 | 100 | TestDeclarations.java:10:8:10:14 | ... > ... | -| TestDeclarations.java:11:4:14:4 | stmt | TestDeclarations.java:12:5:12:11 | stmt | -| TestDeclarations.java:12:5:12:10 | ...=... | TestDeclarations.java:13:5:13:10 | stmt | -| TestDeclarations.java:12:5:12:11 | stmt | TestDeclarations.java:12:9:12:10 | 10 | +| TestDeclarations.java:11:4:14:4 | { ... } | TestDeclarations.java:12:5:12:11 | ...; | +| TestDeclarations.java:12:5:12:10 | ...=... | TestDeclarations.java:13:5:13:10 | ...; | +| TestDeclarations.java:12:5:12:11 | ...; | TestDeclarations.java:12:9:12:10 | 10 | | TestDeclarations.java:12:9:12:10 | 10 | TestDeclarations.java:12:5:12:10 | ...=... | -| TestDeclarations.java:13:5:13:9 | ...=... | TestDeclarations.java:15:4:15:15 | stmt | -| TestDeclarations.java:13:5:13:10 | stmt | TestDeclarations.java:13:9:13:9 | c | +| TestDeclarations.java:13:5:13:9 | ...=... | TestDeclarations.java:15:4:15:15 | if (...) | +| TestDeclarations.java:13:5:13:10 | ...; | TestDeclarations.java:13:9:13:9 | c | | TestDeclarations.java:13:9:13:9 | c | TestDeclarations.java:13:5:13:9 | ...=... | -| TestDeclarations.java:15:4:15:15 | stmt | TestDeclarations.java:15:8:15:8 | a | +| TestDeclarations.java:15:4:15:15 | if (...) | TestDeclarations.java:15:8:15:8 | a | | TestDeclarations.java:15:8:15:8 | a | TestDeclarations.java:15:13:15:14 | 10 | -| TestDeclarations.java:15:8:15:14 | ... == ... | TestDeclarations.java:16:5:16:10 | stmt | -| TestDeclarations.java:15:8:15:14 | ... == ... | TestDeclarations.java:17:4:17:15 | stmt | +| TestDeclarations.java:15:8:15:14 | ... == ... | TestDeclarations.java:16:5:16:10 | break | +| TestDeclarations.java:15:8:15:14 | ... == ... | TestDeclarations.java:17:4:17:15 | if (...) | | TestDeclarations.java:15:13:15:14 | 10 | TestDeclarations.java:15:8:15:14 | ... == ... | -| TestDeclarations.java:16:5:16:10 | stmt | TestDeclarations.java:20:3:20:10 | stmt | -| TestDeclarations.java:17:4:17:15 | stmt | TestDeclarations.java:17:8:17:8 | a | +| TestDeclarations.java:16:5:16:10 | break | TestDeclarations.java:20:3:20:10 | local variable declaration | +| TestDeclarations.java:17:4:17:15 | if (...) | TestDeclarations.java:17:8:17:8 | a | | TestDeclarations.java:17:8:17:8 | a | TestDeclarations.java:17:13:17:14 | 20 | | TestDeclarations.java:17:8:17:14 | ... == ... | TestDeclarations.java:7:9:7:12 | true | | TestDeclarations.java:17:8:17:14 | ... == ... | TestDeclarations.java:18:12:18:12 | c | | TestDeclarations.java:17:13:17:14 | 20 | TestDeclarations.java:17:8:17:14 | ... == ... | -| TestDeclarations.java:18:5:18:13 | stmt | TestDeclarations.java:2:6:2:21 | declarationTests | -| TestDeclarations.java:18:12:18:12 | c | TestDeclarations.java:18:5:18:13 | stmt | -| TestDeclarations.java:20:3:20:10 | stmt | TestDeclarations.java:20:7:20:7 | x | +| TestDeclarations.java:18:5:18:13 | return ... | TestDeclarations.java:2:6:2:21 | declarationTests | +| TestDeclarations.java:18:12:18:12 | c | TestDeclarations.java:18:5:18:13 | return ... | +| TestDeclarations.java:20:3:20:10 | local variable declaration | TestDeclarations.java:20:7:20:7 | x | | TestDeclarations.java:20:7:20:7 | x | TestDeclarations.java:20:9:20:9 | y | -| TestDeclarations.java:20:9:20:9 | y | TestDeclarations.java:21:3:21:8 | stmt | -| TestDeclarations.java:21:3:21:7 | ...=... | TestDeclarations.java:22:3:22:8 | stmt | -| TestDeclarations.java:21:3:21:8 | stmt | TestDeclarations.java:21:7:21:7 | 3 | +| TestDeclarations.java:20:9:20:9 | y | TestDeclarations.java:21:3:21:8 | ...; | +| TestDeclarations.java:21:3:21:7 | ...=... | TestDeclarations.java:22:3:22:8 | ...; | +| TestDeclarations.java:21:3:21:8 | ...; | TestDeclarations.java:21:7:21:7 | 3 | | TestDeclarations.java:21:7:21:7 | 3 | TestDeclarations.java:21:3:21:7 | ...=... | | TestDeclarations.java:22:3:22:7 | ...=... | TestDeclarations.java:23:10:23:10 | b | -| TestDeclarations.java:22:3:22:8 | stmt | TestDeclarations.java:22:7:22:7 | 4 | +| TestDeclarations.java:22:3:22:8 | ...; | TestDeclarations.java:22:7:22:7 | 4 | | TestDeclarations.java:22:7:22:7 | 4 | TestDeclarations.java:22:3:22:7 | ...=... | -| TestDeclarations.java:23:3:23:11 | stmt | TestDeclarations.java:2:6:2:21 | declarationTests | -| TestDeclarations.java:23:10:23:10 | b | TestDeclarations.java:23:3:23:11 | stmt | +| TestDeclarations.java:23:3:23:11 | return ... | TestDeclarations.java:2:6:2:21 | declarationTests | +| TestDeclarations.java:23:10:23:10 | b | TestDeclarations.java:23:3:23:11 | return ... | diff --git a/java/ql/test/library-tests/successors/TestFinally/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestFinally/FalseSuccessors.expected index f94fa777023..de8e32d0b38 100644 --- a/java/ql/test/library-tests/successors/TestFinally/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestFinally/FalseSuccessors.expected @@ -1,15 +1,15 @@ -| TestFinally.java:12:9:12:14 | ... == ... | TestFinally.java:16:5:39:5 | stmt | -| TestFinally.java:19:10:19:15 | ... == ... | TestFinally.java:23:6:23:32 | stmt | -| TestFinally.java:27:10:27:15 | ... == ... | TestFinally.java:32:5:39:5 | stmt | -| TestFinally.java:34:10:34:15 | ... == ... | TestFinally.java:38:6:38:36 | stmt | -| TestFinally.java:47:10:47:15 | ... == ... | TestFinally.java:51:6:51:32 | stmt | -| TestFinally.java:55:10:55:15 | ... == ... | TestFinally.java:60:5:67:5 | stmt | -| TestFinally.java:62:10:62:15 | ... == ... | TestFinally.java:66:6:66:36 | stmt | -| TestFinally.java:68:9:68:14 | ... == ... | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:75:9:75:14 | ... == ... | TestFinally.java:79:5:79:35 | stmt | -| TestFinally.java:91:9:91:14 | ... == ... | TestFinally.java:95:5:95:31 | stmt | -| TestFinally.java:99:9:99:14 | ... == ... | TestFinally.java:104:4:111:4 | stmt | -| TestFinally.java:106:9:106:14 | ... == ... | TestFinally.java:110:5:110:35 | stmt | -| TestFinally.java:126:8:126:13 | ... == ... | TestFinally.java:130:4:130:30 | stmt | -| TestFinally.java:134:8:134:13 | ... == ... | TestFinally.java:139:3:146:3 | stmt | -| TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:145:4:145:34 | stmt | +| TestFinally.java:12:9:12:14 | ... == ... | TestFinally.java:16:5:39:5 | try ... | +| TestFinally.java:19:10:19:15 | ... == ... | TestFinally.java:23:6:23:32 | ...; | +| TestFinally.java:27:10:27:15 | ... == ... | TestFinally.java:32:5:39:5 | { ... } | +| TestFinally.java:34:10:34:15 | ... == ... | TestFinally.java:38:6:38:36 | ...; | +| TestFinally.java:47:10:47:15 | ... == ... | TestFinally.java:51:6:51:32 | ...; | +| TestFinally.java:55:10:55:15 | ... == ... | TestFinally.java:60:5:67:5 | { ... } | +| TestFinally.java:62:10:62:15 | ... == ... | TestFinally.java:66:6:66:36 | ...; | +| TestFinally.java:68:9:68:14 | ... == ... | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:75:9:75:14 | ... == ... | TestFinally.java:79:5:79:35 | ...; | +| TestFinally.java:91:9:91:14 | ... == ... | TestFinally.java:95:5:95:31 | ...; | +| TestFinally.java:99:9:99:14 | ... == ... | TestFinally.java:104:4:111:4 | { ... } | +| TestFinally.java:106:9:106:14 | ... == ... | TestFinally.java:110:5:110:35 | ...; | +| TestFinally.java:126:8:126:13 | ... == ... | TestFinally.java:130:4:130:30 | ...; | +| TestFinally.java:134:8:134:13 | ... == ... | TestFinally.java:139:3:146:3 | { ... } | +| TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:145:4:145:34 | ...; | diff --git a/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected b/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected index df7b4e57ebf..baf6e960eb8 100644 --- a/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected @@ -1,337 +1,337 @@ -| TestFinally.java:3:14:3:24 | stmt | TestFinally.java:3:14:3:24 | super(...) | | TestFinally.java:3:14:3:24 | super(...) | TestFinally.java:3:14:3:24 | TestFinally | -| TestFinally.java:5:2:149:2 | stmt | TestFinally.java:6:3:6:13 | stmt | -| TestFinally.java:6:3:6:13 | stmt | TestFinally.java:6:11:6:12 | 12 | -| TestFinally.java:6:7:6:12 | z | TestFinally.java:7:3:120:3 | stmt | +| TestFinally.java:3:14:3:24 | { ... } | TestFinally.java:3:14:3:24 | super(...) | +| TestFinally.java:5:2:149:2 | { ... } | TestFinally.java:6:3:6:13 | local variable declaration | +| TestFinally.java:6:3:6:13 | local variable declaration | TestFinally.java:6:11:6:12 | 12 | +| TestFinally.java:6:7:6:12 | z | TestFinally.java:7:3:120:3 | try ... | | TestFinally.java:6:11:6:12 | 12 | TestFinally.java:6:7:6:12 | z | -| TestFinally.java:7:3:120:3 | stmt | TestFinally.java:8:3:86:3 | stmt | -| TestFinally.java:8:3:86:3 | stmt | TestFinally.java:9:4:80:4 | stmt | -| TestFinally.java:9:4:80:4 | stmt | TestFinally.java:10:4:41:4 | stmt | -| TestFinally.java:10:4:41:4 | stmt | TestFinally.java:11:5:11:31 | stmt | +| TestFinally.java:7:3:120:3 | try ... | TestFinally.java:8:3:86:3 | { ... } | +| TestFinally.java:8:3:86:3 | { ... } | TestFinally.java:9:4:80:4 | try ... | +| TestFinally.java:9:4:80:4 | try ... | TestFinally.java:10:4:41:4 | { ... } | +| TestFinally.java:10:4:41:4 | { ... } | TestFinally.java:11:5:11:31 | ...; | | TestFinally.java:11:5:11:14 | System.out | TestFinally.java:11:24:11:29 | "Try1" | -| TestFinally.java:11:5:11:30 | println(...) | TestFinally.java:12:5:12:15 | stmt | -| TestFinally.java:11:5:11:30 | println(...) | TestFinally.java:41:6:41:25 | stmt | -| TestFinally.java:11:5:11:30 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:11:5:11:31 | stmt | TestFinally.java:11:5:11:14 | System.out | +| TestFinally.java:11:5:11:30 | println(...) | TestFinally.java:12:5:12:15 | if (...) | +| TestFinally.java:11:5:11:30 | println(...) | TestFinally.java:41:6:41:25 | catch (...) | +| TestFinally.java:11:5:11:30 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:11:5:11:31 | ...; | TestFinally.java:11:5:11:14 | System.out | | TestFinally.java:11:24:11:29 | "Try1" | TestFinally.java:11:5:11:30 | println(...) | -| TestFinally.java:12:5:12:15 | stmt | TestFinally.java:12:9:12:9 | z | +| TestFinally.java:12:5:12:15 | if (...) | TestFinally.java:12:9:12:9 | z | | TestFinally.java:12:9:12:9 | z | TestFinally.java:12:14:12:14 | 1 | -| TestFinally.java:12:9:12:14 | ... == ... | TestFinally.java:13:5:15:5 | stmt | -| TestFinally.java:12:9:12:14 | ... == ... | TestFinally.java:16:5:39:5 | stmt | +| TestFinally.java:12:9:12:14 | ... == ... | TestFinally.java:13:5:15:5 | { ... } | +| TestFinally.java:12:9:12:14 | ... == ... | TestFinally.java:16:5:39:5 | try ... | | TestFinally.java:12:14:12:14 | 1 | TestFinally.java:12:9:12:14 | ... == ... | -| TestFinally.java:13:5:15:5 | stmt | TestFinally.java:14:6:14:12 | stmt | -| TestFinally.java:14:6:14:12 | stmt | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:16:5:39:5 | stmt | TestFinally.java:17:5:24:5 | stmt | -| TestFinally.java:17:5:24:5 | stmt | TestFinally.java:18:6:18:32 | stmt | +| TestFinally.java:13:5:15:5 | { ... } | TestFinally.java:14:6:14:12 | return ... | +| TestFinally.java:14:6:14:12 | return ... | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:16:5:39:5 | try ... | TestFinally.java:17:5:24:5 | { ... } | +| TestFinally.java:17:5:24:5 | { ... } | TestFinally.java:18:6:18:32 | ...; | | TestFinally.java:18:6:18:15 | System.out | TestFinally.java:18:25:18:30 | "Try1" | -| TestFinally.java:18:6:18:31 | println(...) | TestFinally.java:19:6:19:16 | stmt | -| TestFinally.java:18:6:18:31 | println(...) | TestFinally.java:24:7:24:26 | stmt | -| TestFinally.java:18:6:18:31 | println(...) | TestFinally.java:32:5:39:5 | stmt | -| TestFinally.java:18:6:18:32 | stmt | TestFinally.java:18:6:18:15 | System.out | +| TestFinally.java:18:6:18:31 | println(...) | TestFinally.java:19:6:19:16 | if (...) | +| TestFinally.java:18:6:18:31 | println(...) | TestFinally.java:24:7:24:26 | catch (...) | +| TestFinally.java:18:6:18:31 | println(...) | TestFinally.java:32:5:39:5 | { ... } | +| TestFinally.java:18:6:18:32 | ...; | TestFinally.java:18:6:18:15 | System.out | | TestFinally.java:18:25:18:30 | "Try1" | TestFinally.java:18:6:18:31 | println(...) | -| TestFinally.java:19:6:19:16 | stmt | TestFinally.java:19:10:19:10 | z | +| TestFinally.java:19:6:19:16 | if (...) | TestFinally.java:19:10:19:10 | z | | TestFinally.java:19:10:19:10 | z | TestFinally.java:19:15:19:15 | 1 | -| TestFinally.java:19:10:19:15 | ... == ... | TestFinally.java:20:6:22:6 | stmt | -| TestFinally.java:19:10:19:15 | ... == ... | TestFinally.java:23:6:23:32 | stmt | +| TestFinally.java:19:10:19:15 | ... == ... | TestFinally.java:20:6:22:6 | { ... } | +| TestFinally.java:19:10:19:15 | ... == ... | TestFinally.java:23:6:23:32 | ...; | | TestFinally.java:19:15:19:15 | 1 | TestFinally.java:19:10:19:15 | ... == ... | -| TestFinally.java:20:6:22:6 | stmt | TestFinally.java:21:7:21:13 | stmt | -| TestFinally.java:21:7:21:13 | stmt | TestFinally.java:32:5:39:5 | stmt | +| TestFinally.java:20:6:22:6 | { ... } | TestFinally.java:21:7:21:13 | return ... | +| TestFinally.java:21:7:21:13 | return ... | TestFinally.java:32:5:39:5 | { ... } | | TestFinally.java:23:6:23:15 | System.out | TestFinally.java:23:25:23:30 | "Try2" | -| TestFinally.java:23:6:23:31 | println(...) | TestFinally.java:24:7:24:26 | stmt | -| TestFinally.java:23:6:23:31 | println(...) | TestFinally.java:32:5:39:5 | stmt | -| TestFinally.java:23:6:23:32 | stmt | TestFinally.java:23:6:23:15 | System.out | +| TestFinally.java:23:6:23:31 | println(...) | TestFinally.java:24:7:24:26 | catch (...) | +| TestFinally.java:23:6:23:31 | println(...) | TestFinally.java:32:5:39:5 | { ... } | +| TestFinally.java:23:6:23:32 | ...; | TestFinally.java:23:6:23:15 | System.out | | TestFinally.java:23:25:23:30 | "Try2" | TestFinally.java:23:6:23:31 | println(...) | -| TestFinally.java:24:7:24:26 | stmt | TestFinally.java:24:24:24:25 | ex | -| TestFinally.java:24:24:24:25 | ex | TestFinally.java:25:5:31:5 | stmt | -| TestFinally.java:25:5:31:5 | stmt | TestFinally.java:26:6:26:37 | stmt | +| TestFinally.java:24:7:24:26 | catch (...) | TestFinally.java:24:24:24:25 | ex | +| TestFinally.java:24:24:24:25 | ex | TestFinally.java:25:5:31:5 | { ... } | +| TestFinally.java:25:5:31:5 | { ... } | TestFinally.java:26:6:26:37 | ...; | | TestFinally.java:26:6:26:15 | System.out | TestFinally.java:26:25:26:35 | "Exception" | -| TestFinally.java:26:6:26:36 | println(...) | TestFinally.java:27:6:27:16 | stmt | -| TestFinally.java:26:6:26:36 | println(...) | TestFinally.java:32:5:39:5 | stmt | -| TestFinally.java:26:6:26:37 | stmt | TestFinally.java:26:6:26:15 | System.out | +| TestFinally.java:26:6:26:36 | println(...) | TestFinally.java:27:6:27:16 | if (...) | +| TestFinally.java:26:6:26:36 | println(...) | TestFinally.java:32:5:39:5 | { ... } | +| TestFinally.java:26:6:26:37 | ...; | TestFinally.java:26:6:26:15 | System.out | | TestFinally.java:26:25:26:35 | "Exception" | TestFinally.java:26:6:26:36 | println(...) | -| TestFinally.java:27:6:27:16 | stmt | TestFinally.java:27:10:27:10 | z | +| TestFinally.java:27:6:27:16 | if (...) | TestFinally.java:27:10:27:10 | z | | TestFinally.java:27:10:27:10 | z | TestFinally.java:27:15:27:15 | 1 | -| TestFinally.java:27:10:27:15 | ... == ... | TestFinally.java:28:6:30:6 | stmt | -| TestFinally.java:27:10:27:15 | ... == ... | TestFinally.java:32:5:39:5 | stmt | +| TestFinally.java:27:10:27:15 | ... == ... | TestFinally.java:28:6:30:6 | { ... } | +| TestFinally.java:27:10:27:15 | ... == ... | TestFinally.java:32:5:39:5 | { ... } | | TestFinally.java:27:15:27:15 | 1 | TestFinally.java:27:10:27:15 | ... == ... | -| TestFinally.java:28:6:30:6 | stmt | TestFinally.java:29:7:29:13 | stmt | -| TestFinally.java:29:7:29:13 | stmt | TestFinally.java:32:5:39:5 | stmt | -| TestFinally.java:32:5:39:5 | stmt | TestFinally.java:33:6:33:35 | stmt | +| TestFinally.java:28:6:30:6 | { ... } | TestFinally.java:29:7:29:13 | return ... | +| TestFinally.java:29:7:29:13 | return ... | TestFinally.java:32:5:39:5 | { ... } | +| TestFinally.java:32:5:39:5 | { ... } | TestFinally.java:33:6:33:35 | ...; | | TestFinally.java:33:6:33:15 | System.out | TestFinally.java:33:25:33:33 | "Finally" | -| TestFinally.java:33:6:33:34 | println(...) | TestFinally.java:34:6:34:16 | stmt | -| TestFinally.java:33:6:33:34 | println(...) | TestFinally.java:41:6:41:25 | stmt | -| TestFinally.java:33:6:33:34 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:33:6:33:35 | stmt | TestFinally.java:33:6:33:15 | System.out | +| TestFinally.java:33:6:33:34 | println(...) | TestFinally.java:34:6:34:16 | if (...) | +| TestFinally.java:33:6:33:34 | println(...) | TestFinally.java:41:6:41:25 | catch (...) | +| TestFinally.java:33:6:33:34 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:33:6:33:35 | ...; | TestFinally.java:33:6:33:15 | System.out | | TestFinally.java:33:25:33:33 | "Finally" | TestFinally.java:33:6:33:34 | println(...) | -| TestFinally.java:34:6:34:16 | stmt | TestFinally.java:34:10:34:10 | z | +| TestFinally.java:34:6:34:16 | if (...) | TestFinally.java:34:10:34:10 | z | | TestFinally.java:34:10:34:10 | z | TestFinally.java:34:15:34:15 | 1 | -| TestFinally.java:34:10:34:15 | ... == ... | TestFinally.java:35:6:37:6 | stmt | -| TestFinally.java:34:10:34:15 | ... == ... | TestFinally.java:38:6:38:36 | stmt | +| TestFinally.java:34:10:34:15 | ... == ... | TestFinally.java:35:6:37:6 | { ... } | +| TestFinally.java:34:10:34:15 | ... == ... | TestFinally.java:38:6:38:36 | ...; | | TestFinally.java:34:15:34:15 | 1 | TestFinally.java:34:10:34:15 | ... == ... | -| TestFinally.java:35:6:37:6 | stmt | TestFinally.java:36:7:36:13 | stmt | -| TestFinally.java:36:7:36:13 | stmt | TestFinally.java:73:4:80:4 | stmt | +| TestFinally.java:35:6:37:6 | { ... } | TestFinally.java:36:7:36:13 | return ... | +| TestFinally.java:36:7:36:13 | return ... | TestFinally.java:73:4:80:4 | { ... } | | TestFinally.java:38:6:38:15 | System.out | TestFinally.java:38:25:38:34 | "Finally2" | -| TestFinally.java:38:6:38:35 | println(...) | TestFinally.java:40:5:40:31 | stmt | -| TestFinally.java:38:6:38:35 | println(...) | TestFinally.java:41:6:41:25 | stmt | -| TestFinally.java:38:6:38:35 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:38:6:38:36 | stmt | TestFinally.java:38:6:38:15 | System.out | +| TestFinally.java:38:6:38:35 | println(...) | TestFinally.java:40:5:40:31 | ...; | +| TestFinally.java:38:6:38:35 | println(...) | TestFinally.java:41:6:41:25 | catch (...) | +| TestFinally.java:38:6:38:35 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:38:6:38:36 | ...; | TestFinally.java:38:6:38:15 | System.out | | TestFinally.java:38:25:38:34 | "Finally2" | TestFinally.java:38:6:38:35 | println(...) | | TestFinally.java:40:5:40:14 | System.out | TestFinally.java:40:24:40:29 | "Try2" | -| TestFinally.java:40:5:40:30 | println(...) | TestFinally.java:41:6:41:25 | stmt | -| TestFinally.java:40:5:40:30 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:40:5:40:31 | stmt | TestFinally.java:40:5:40:14 | System.out | +| TestFinally.java:40:5:40:30 | println(...) | TestFinally.java:41:6:41:25 | catch (...) | +| TestFinally.java:40:5:40:30 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:40:5:40:31 | ...; | TestFinally.java:40:5:40:14 | System.out | | TestFinally.java:40:24:40:29 | "Try2" | TestFinally.java:40:5:40:30 | println(...) | -| TestFinally.java:41:6:41:25 | stmt | TestFinally.java:41:23:41:24 | ex | -| TestFinally.java:41:23:41:24 | ex | TestFinally.java:42:4:72:4 | stmt | -| TestFinally.java:42:4:72:4 | stmt | TestFinally.java:43:5:43:36 | stmt | +| TestFinally.java:41:6:41:25 | catch (...) | TestFinally.java:41:23:41:24 | ex | +| TestFinally.java:41:23:41:24 | ex | TestFinally.java:42:4:72:4 | { ... } | +| TestFinally.java:42:4:72:4 | { ... } | TestFinally.java:43:5:43:36 | ...; | | TestFinally.java:43:5:43:14 | System.out | TestFinally.java:43:24:43:34 | "Exception" | -| TestFinally.java:43:5:43:35 | println(...) | TestFinally.java:44:5:67:5 | stmt | -| TestFinally.java:43:5:43:35 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:43:5:43:36 | stmt | TestFinally.java:43:5:43:14 | System.out | +| TestFinally.java:43:5:43:35 | println(...) | TestFinally.java:44:5:67:5 | try ... | +| TestFinally.java:43:5:43:35 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:43:5:43:36 | ...; | TestFinally.java:43:5:43:14 | System.out | | TestFinally.java:43:24:43:34 | "Exception" | TestFinally.java:43:5:43:35 | println(...) | -| TestFinally.java:44:5:67:5 | stmt | TestFinally.java:45:5:52:5 | stmt | -| TestFinally.java:45:5:52:5 | stmt | TestFinally.java:46:6:46:32 | stmt | +| TestFinally.java:44:5:67:5 | try ... | TestFinally.java:45:5:52:5 | { ... } | +| TestFinally.java:45:5:52:5 | { ... } | TestFinally.java:46:6:46:32 | ...; | | TestFinally.java:46:6:46:15 | System.out | TestFinally.java:46:25:46:30 | "Try1" | -| TestFinally.java:46:6:46:31 | println(...) | TestFinally.java:47:6:47:16 | stmt | -| TestFinally.java:46:6:46:31 | println(...) | TestFinally.java:52:7:52:27 | stmt | -| TestFinally.java:46:6:46:31 | println(...) | TestFinally.java:60:5:67:5 | stmt | -| TestFinally.java:46:6:46:32 | stmt | TestFinally.java:46:6:46:15 | System.out | +| TestFinally.java:46:6:46:31 | println(...) | TestFinally.java:47:6:47:16 | if (...) | +| TestFinally.java:46:6:46:31 | println(...) | TestFinally.java:52:7:52:27 | catch (...) | +| TestFinally.java:46:6:46:31 | println(...) | TestFinally.java:60:5:67:5 | { ... } | +| TestFinally.java:46:6:46:32 | ...; | TestFinally.java:46:6:46:15 | System.out | | TestFinally.java:46:25:46:30 | "Try1" | TestFinally.java:46:6:46:31 | println(...) | -| TestFinally.java:47:6:47:16 | stmt | TestFinally.java:47:10:47:10 | z | +| TestFinally.java:47:6:47:16 | if (...) | TestFinally.java:47:10:47:10 | z | | TestFinally.java:47:10:47:10 | z | TestFinally.java:47:15:47:15 | 1 | -| TestFinally.java:47:10:47:15 | ... == ... | TestFinally.java:48:6:50:6 | stmt | -| TestFinally.java:47:10:47:15 | ... == ... | TestFinally.java:51:6:51:32 | stmt | +| TestFinally.java:47:10:47:15 | ... == ... | TestFinally.java:48:6:50:6 | { ... } | +| TestFinally.java:47:10:47:15 | ... == ... | TestFinally.java:51:6:51:32 | ...; | | TestFinally.java:47:15:47:15 | 1 | TestFinally.java:47:10:47:15 | ... == ... | -| TestFinally.java:48:6:50:6 | stmt | TestFinally.java:49:7:49:13 | stmt | -| TestFinally.java:49:7:49:13 | stmt | TestFinally.java:60:5:67:5 | stmt | +| TestFinally.java:48:6:50:6 | { ... } | TestFinally.java:49:7:49:13 | return ... | +| TestFinally.java:49:7:49:13 | return ... | TestFinally.java:60:5:67:5 | { ... } | | TestFinally.java:51:6:51:15 | System.out | TestFinally.java:51:25:51:30 | "Try2" | -| TestFinally.java:51:6:51:31 | println(...) | TestFinally.java:52:7:52:27 | stmt | -| TestFinally.java:51:6:51:31 | println(...) | TestFinally.java:60:5:67:5 | stmt | -| TestFinally.java:51:6:51:32 | stmt | TestFinally.java:51:6:51:15 | System.out | +| TestFinally.java:51:6:51:31 | println(...) | TestFinally.java:52:7:52:27 | catch (...) | +| TestFinally.java:51:6:51:31 | println(...) | TestFinally.java:60:5:67:5 | { ... } | +| TestFinally.java:51:6:51:32 | ...; | TestFinally.java:51:6:51:15 | System.out | | TestFinally.java:51:25:51:30 | "Try2" | TestFinally.java:51:6:51:31 | println(...) | -| TestFinally.java:52:7:52:27 | stmt | TestFinally.java:52:24:52:26 | ex2 | -| TestFinally.java:52:24:52:26 | ex2 | TestFinally.java:53:5:59:5 | stmt | -| TestFinally.java:53:5:59:5 | stmt | TestFinally.java:54:6:54:37 | stmt | +| TestFinally.java:52:7:52:27 | catch (...) | TestFinally.java:52:24:52:26 | ex2 | +| TestFinally.java:52:24:52:26 | ex2 | TestFinally.java:53:5:59:5 | { ... } | +| TestFinally.java:53:5:59:5 | { ... } | TestFinally.java:54:6:54:37 | ...; | | TestFinally.java:54:6:54:15 | System.out | TestFinally.java:54:25:54:35 | "Exception" | -| TestFinally.java:54:6:54:36 | println(...) | TestFinally.java:55:6:55:16 | stmt | -| TestFinally.java:54:6:54:36 | println(...) | TestFinally.java:60:5:67:5 | stmt | -| TestFinally.java:54:6:54:37 | stmt | TestFinally.java:54:6:54:15 | System.out | +| TestFinally.java:54:6:54:36 | println(...) | TestFinally.java:55:6:55:16 | if (...) | +| TestFinally.java:54:6:54:36 | println(...) | TestFinally.java:60:5:67:5 | { ... } | +| TestFinally.java:54:6:54:37 | ...; | TestFinally.java:54:6:54:15 | System.out | | TestFinally.java:54:25:54:35 | "Exception" | TestFinally.java:54:6:54:36 | println(...) | -| TestFinally.java:55:6:55:16 | stmt | TestFinally.java:55:10:55:10 | z | +| TestFinally.java:55:6:55:16 | if (...) | TestFinally.java:55:10:55:10 | z | | TestFinally.java:55:10:55:10 | z | TestFinally.java:55:15:55:15 | 1 | -| TestFinally.java:55:10:55:15 | ... == ... | TestFinally.java:56:6:58:6 | stmt | -| TestFinally.java:55:10:55:15 | ... == ... | TestFinally.java:60:5:67:5 | stmt | +| TestFinally.java:55:10:55:15 | ... == ... | TestFinally.java:56:6:58:6 | { ... } | +| TestFinally.java:55:10:55:15 | ... == ... | TestFinally.java:60:5:67:5 | { ... } | | TestFinally.java:55:15:55:15 | 1 | TestFinally.java:55:10:55:15 | ... == ... | -| TestFinally.java:56:6:58:6 | stmt | TestFinally.java:57:7:57:13 | stmt | -| TestFinally.java:57:7:57:13 | stmt | TestFinally.java:60:5:67:5 | stmt | -| TestFinally.java:60:5:67:5 | stmt | TestFinally.java:61:6:61:35 | stmt | +| TestFinally.java:56:6:58:6 | { ... } | TestFinally.java:57:7:57:13 | return ... | +| TestFinally.java:57:7:57:13 | return ... | TestFinally.java:60:5:67:5 | { ... } | +| TestFinally.java:60:5:67:5 | { ... } | TestFinally.java:61:6:61:35 | ...; | | TestFinally.java:61:6:61:15 | System.out | TestFinally.java:61:25:61:33 | "Finally" | -| TestFinally.java:61:6:61:34 | println(...) | TestFinally.java:62:6:62:16 | stmt | -| TestFinally.java:61:6:61:34 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:61:6:61:35 | stmt | TestFinally.java:61:6:61:15 | System.out | +| TestFinally.java:61:6:61:34 | println(...) | TestFinally.java:62:6:62:16 | if (...) | +| TestFinally.java:61:6:61:34 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:61:6:61:35 | ...; | TestFinally.java:61:6:61:15 | System.out | | TestFinally.java:61:25:61:33 | "Finally" | TestFinally.java:61:6:61:34 | println(...) | -| TestFinally.java:62:6:62:16 | stmt | TestFinally.java:62:10:62:10 | z | +| TestFinally.java:62:6:62:16 | if (...) | TestFinally.java:62:10:62:10 | z | | TestFinally.java:62:10:62:10 | z | TestFinally.java:62:15:62:15 | 1 | -| TestFinally.java:62:10:62:15 | ... == ... | TestFinally.java:63:6:65:6 | stmt | -| TestFinally.java:62:10:62:15 | ... == ... | TestFinally.java:66:6:66:36 | stmt | +| TestFinally.java:62:10:62:15 | ... == ... | TestFinally.java:63:6:65:6 | { ... } | +| TestFinally.java:62:10:62:15 | ... == ... | TestFinally.java:66:6:66:36 | ...; | | TestFinally.java:62:15:62:15 | 1 | TestFinally.java:62:10:62:15 | ... == ... | -| TestFinally.java:63:6:65:6 | stmt | TestFinally.java:64:7:64:13 | stmt | -| TestFinally.java:64:7:64:13 | stmt | TestFinally.java:73:4:80:4 | stmt | +| TestFinally.java:63:6:65:6 | { ... } | TestFinally.java:64:7:64:13 | return ... | +| TestFinally.java:64:7:64:13 | return ... | TestFinally.java:73:4:80:4 | { ... } | | TestFinally.java:66:6:66:15 | System.out | TestFinally.java:66:25:66:34 | "Finally2" | -| TestFinally.java:66:6:66:35 | println(...) | TestFinally.java:68:5:68:15 | stmt | -| TestFinally.java:66:6:66:35 | println(...) | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:66:6:66:36 | stmt | TestFinally.java:66:6:66:15 | System.out | +| TestFinally.java:66:6:66:35 | println(...) | TestFinally.java:68:5:68:15 | if (...) | +| TestFinally.java:66:6:66:35 | println(...) | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:66:6:66:36 | ...; | TestFinally.java:66:6:66:15 | System.out | | TestFinally.java:66:25:66:34 | "Finally2" | TestFinally.java:66:6:66:35 | println(...) | -| TestFinally.java:68:5:68:15 | stmt | TestFinally.java:68:9:68:9 | z | +| TestFinally.java:68:5:68:15 | if (...) | TestFinally.java:68:9:68:9 | z | | TestFinally.java:68:9:68:9 | z | TestFinally.java:68:14:68:14 | 1 | -| TestFinally.java:68:9:68:14 | ... == ... | TestFinally.java:69:5:71:5 | stmt | -| TestFinally.java:68:9:68:14 | ... == ... | TestFinally.java:73:4:80:4 | stmt | +| TestFinally.java:68:9:68:14 | ... == ... | TestFinally.java:69:5:71:5 | { ... } | +| TestFinally.java:68:9:68:14 | ... == ... | TestFinally.java:73:4:80:4 | { ... } | | TestFinally.java:68:14:68:14 | 1 | TestFinally.java:68:9:68:14 | ... == ... | -| TestFinally.java:69:5:71:5 | stmt | TestFinally.java:70:6:70:12 | stmt | -| TestFinally.java:70:6:70:12 | stmt | TestFinally.java:73:4:80:4 | stmt | -| TestFinally.java:73:4:80:4 | stmt | TestFinally.java:74:5:74:34 | stmt | +| TestFinally.java:69:5:71:5 | { ... } | TestFinally.java:70:6:70:12 | return ... | +| TestFinally.java:70:6:70:12 | return ... | TestFinally.java:73:4:80:4 | { ... } | +| TestFinally.java:73:4:80:4 | { ... } | TestFinally.java:74:5:74:34 | ...; | | TestFinally.java:74:5:74:14 | System.out | TestFinally.java:74:24:74:32 | "Finally" | -| TestFinally.java:74:5:74:33 | println(...) | TestFinally.java:75:5:75:15 | stmt | -| TestFinally.java:74:5:74:33 | println(...) | TestFinally.java:86:5:86:23 | stmt | -| TestFinally.java:74:5:74:33 | println(...) | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:74:5:74:34 | stmt | TestFinally.java:74:5:74:14 | System.out | +| TestFinally.java:74:5:74:33 | println(...) | TestFinally.java:75:5:75:15 | if (...) | +| TestFinally.java:74:5:74:33 | println(...) | TestFinally.java:86:5:86:23 | catch (...) | +| TestFinally.java:74:5:74:33 | println(...) | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:74:5:74:34 | ...; | TestFinally.java:74:5:74:14 | System.out | | TestFinally.java:74:24:74:32 | "Finally" | TestFinally.java:74:5:74:33 | println(...) | -| TestFinally.java:75:5:75:15 | stmt | TestFinally.java:75:9:75:9 | z | +| TestFinally.java:75:5:75:15 | if (...) | TestFinally.java:75:9:75:9 | z | | TestFinally.java:75:9:75:9 | z | TestFinally.java:75:14:75:14 | 1 | -| TestFinally.java:75:9:75:14 | ... == ... | TestFinally.java:76:5:78:5 | stmt | -| TestFinally.java:75:9:75:14 | ... == ... | TestFinally.java:79:5:79:35 | stmt | +| TestFinally.java:75:9:75:14 | ... == ... | TestFinally.java:76:5:78:5 | { ... } | +| TestFinally.java:75:9:75:14 | ... == ... | TestFinally.java:79:5:79:35 | ...; | | TestFinally.java:75:14:75:14 | 1 | TestFinally.java:75:9:75:14 | ... == ... | -| TestFinally.java:76:5:78:5 | stmt | TestFinally.java:77:6:77:12 | stmt | -| TestFinally.java:77:6:77:12 | stmt | TestFinally.java:116:3:120:3 | stmt | +| TestFinally.java:76:5:78:5 | { ... } | TestFinally.java:77:6:77:12 | return ... | +| TestFinally.java:77:6:77:12 | return ... | TestFinally.java:116:3:120:3 | { ... } | | TestFinally.java:79:5:79:14 | System.out | TestFinally.java:79:24:79:33 | "Finally2" | -| TestFinally.java:79:5:79:34 | println(...) | TestFinally.java:81:4:81:29 | stmt | -| TestFinally.java:79:5:79:34 | println(...) | TestFinally.java:86:5:86:23 | stmt | -| TestFinally.java:79:5:79:34 | println(...) | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:79:5:79:35 | stmt | TestFinally.java:79:5:79:14 | System.out | +| TestFinally.java:79:5:79:34 | println(...) | TestFinally.java:81:4:81:29 | ...; | +| TestFinally.java:79:5:79:34 | println(...) | TestFinally.java:86:5:86:23 | catch (...) | +| TestFinally.java:79:5:79:34 | println(...) | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:79:5:79:35 | ...; | TestFinally.java:79:5:79:14 | System.out | | TestFinally.java:79:24:79:33 | "Finally2" | TestFinally.java:79:5:79:34 | println(...) | | TestFinally.java:81:4:81:13 | System.out | TestFinally.java:81:23:81:27 | "Foo" | -| TestFinally.java:81:4:81:28 | println(...) | TestFinally.java:82:4:82:18 | stmt | -| TestFinally.java:81:4:81:28 | println(...) | TestFinally.java:86:5:86:23 | stmt | -| TestFinally.java:81:4:81:28 | println(...) | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:81:4:81:29 | stmt | TestFinally.java:81:4:81:13 | System.out | +| TestFinally.java:81:4:81:28 | println(...) | TestFinally.java:82:4:82:18 | local variable declaration | +| TestFinally.java:81:4:81:28 | println(...) | TestFinally.java:86:5:86:23 | catch (...) | +| TestFinally.java:81:4:81:28 | println(...) | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:81:4:81:29 | ...; | TestFinally.java:81:4:81:13 | System.out | | TestFinally.java:81:23:81:27 | "Foo" | TestFinally.java:81:4:81:28 | println(...) | -| TestFinally.java:82:4:82:18 | stmt | TestFinally.java:82:12:82:13 | 12 | -| TestFinally.java:82:8:82:17 | y | TestFinally.java:83:4:83:29 | stmt | +| TestFinally.java:82:4:82:18 | local variable declaration | TestFinally.java:82:12:82:13 | 12 | +| TestFinally.java:82:8:82:17 | y | TestFinally.java:83:4:83:29 | ...; | | TestFinally.java:82:12:82:13 | 12 | TestFinally.java:82:17:82:17 | 3 | | TestFinally.java:82:12:82:17 | ... + ... | TestFinally.java:82:8:82:17 | y | | TestFinally.java:82:17:82:17 | 3 | TestFinally.java:82:12:82:17 | ... + ... | | TestFinally.java:83:4:83:13 | System.out | TestFinally.java:83:23:83:27 | "Bar" | -| TestFinally.java:83:4:83:28 | println(...) | TestFinally.java:84:4:84:13 | stmt | -| TestFinally.java:83:4:83:28 | println(...) | TestFinally.java:86:5:86:23 | stmt | -| TestFinally.java:83:4:83:28 | println(...) | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:83:4:83:29 | stmt | TestFinally.java:83:4:83:13 | System.out | +| TestFinally.java:83:4:83:28 | println(...) | TestFinally.java:84:4:84:13 | ...; | +| TestFinally.java:83:4:83:28 | println(...) | TestFinally.java:86:5:86:23 | catch (...) | +| TestFinally.java:83:4:83:28 | println(...) | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:83:4:83:29 | ...; | TestFinally.java:83:4:83:13 | System.out | | TestFinally.java:83:23:83:27 | "Bar" | TestFinally.java:83:4:83:28 | println(...) | -| TestFinally.java:84:4:84:12 | ...=... | TestFinally.java:85:4:85:10 | stmt | -| TestFinally.java:84:4:84:13 | stmt | TestFinally.java:84:8:84:8 | y | +| TestFinally.java:84:4:84:12 | ...=... | TestFinally.java:85:4:85:10 | return ... | +| TestFinally.java:84:4:84:13 | ...; | TestFinally.java:84:8:84:8 | y | | TestFinally.java:84:8:84:8 | y | TestFinally.java:84:12:84:12 | 1 | | TestFinally.java:84:8:84:12 | ... + ... | TestFinally.java:84:4:84:12 | ...=... | | TestFinally.java:84:12:84:12 | 1 | TestFinally.java:84:8:84:12 | ... + ... | -| TestFinally.java:85:4:85:10 | stmt | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:86:5:86:23 | stmt | TestFinally.java:86:22:86:22 | e | -| TestFinally.java:86:22:86:22 | e | TestFinally.java:87:3:115:3 | stmt | -| TestFinally.java:87:3:115:3 | stmt | TestFinally.java:88:4:111:4 | stmt | -| TestFinally.java:88:4:111:4 | stmt | TestFinally.java:89:4:96:4 | stmt | -| TestFinally.java:89:4:96:4 | stmt | TestFinally.java:90:5:90:31 | stmt | +| TestFinally.java:85:4:85:10 | return ... | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:86:5:86:23 | catch (...) | TestFinally.java:86:22:86:22 | e | +| TestFinally.java:86:22:86:22 | e | TestFinally.java:87:3:115:3 | { ... } | +| TestFinally.java:87:3:115:3 | { ... } | TestFinally.java:88:4:111:4 | try ... | +| TestFinally.java:88:4:111:4 | try ... | TestFinally.java:89:4:96:4 | { ... } | +| TestFinally.java:89:4:96:4 | { ... } | TestFinally.java:90:5:90:31 | ...; | | TestFinally.java:90:5:90:14 | System.out | TestFinally.java:90:24:90:29 | "Try1" | -| TestFinally.java:90:5:90:30 | println(...) | TestFinally.java:91:5:91:15 | stmt | -| TestFinally.java:90:5:90:30 | println(...) | TestFinally.java:96:6:96:25 | stmt | -| TestFinally.java:90:5:90:30 | println(...) | TestFinally.java:104:4:111:4 | stmt | -| TestFinally.java:90:5:90:31 | stmt | TestFinally.java:90:5:90:14 | System.out | +| TestFinally.java:90:5:90:30 | println(...) | TestFinally.java:91:5:91:15 | if (...) | +| TestFinally.java:90:5:90:30 | println(...) | TestFinally.java:96:6:96:25 | catch (...) | +| TestFinally.java:90:5:90:30 | println(...) | TestFinally.java:104:4:111:4 | { ... } | +| TestFinally.java:90:5:90:31 | ...; | TestFinally.java:90:5:90:14 | System.out | | TestFinally.java:90:24:90:29 | "Try1" | TestFinally.java:90:5:90:30 | println(...) | -| TestFinally.java:91:5:91:15 | stmt | TestFinally.java:91:9:91:9 | z | +| TestFinally.java:91:5:91:15 | if (...) | TestFinally.java:91:9:91:9 | z | | TestFinally.java:91:9:91:9 | z | TestFinally.java:91:14:91:14 | 1 | -| TestFinally.java:91:9:91:14 | ... == ... | TestFinally.java:92:5:94:5 | stmt | -| TestFinally.java:91:9:91:14 | ... == ... | TestFinally.java:95:5:95:31 | stmt | +| TestFinally.java:91:9:91:14 | ... == ... | TestFinally.java:92:5:94:5 | { ... } | +| TestFinally.java:91:9:91:14 | ... == ... | TestFinally.java:95:5:95:31 | ...; | | TestFinally.java:91:14:91:14 | 1 | TestFinally.java:91:9:91:14 | ... == ... | -| TestFinally.java:92:5:94:5 | stmt | TestFinally.java:93:6:93:12 | stmt | -| TestFinally.java:93:6:93:12 | stmt | TestFinally.java:104:4:111:4 | stmt | +| TestFinally.java:92:5:94:5 | { ... } | TestFinally.java:93:6:93:12 | return ... | +| TestFinally.java:93:6:93:12 | return ... | TestFinally.java:104:4:111:4 | { ... } | | TestFinally.java:95:5:95:14 | System.out | TestFinally.java:95:24:95:29 | "Try2" | -| TestFinally.java:95:5:95:30 | println(...) | TestFinally.java:96:6:96:25 | stmt | -| TestFinally.java:95:5:95:30 | println(...) | TestFinally.java:104:4:111:4 | stmt | -| TestFinally.java:95:5:95:31 | stmt | TestFinally.java:95:5:95:14 | System.out | +| TestFinally.java:95:5:95:30 | println(...) | TestFinally.java:96:6:96:25 | catch (...) | +| TestFinally.java:95:5:95:30 | println(...) | TestFinally.java:104:4:111:4 | { ... } | +| TestFinally.java:95:5:95:31 | ...; | TestFinally.java:95:5:95:14 | System.out | | TestFinally.java:95:24:95:29 | "Try2" | TestFinally.java:95:5:95:30 | println(...) | -| TestFinally.java:96:6:96:25 | stmt | TestFinally.java:96:23:96:24 | ex | -| TestFinally.java:96:23:96:24 | ex | TestFinally.java:97:4:103:4 | stmt | -| TestFinally.java:97:4:103:4 | stmt | TestFinally.java:98:5:98:36 | stmt | +| TestFinally.java:96:6:96:25 | catch (...) | TestFinally.java:96:23:96:24 | ex | +| TestFinally.java:96:23:96:24 | ex | TestFinally.java:97:4:103:4 | { ... } | +| TestFinally.java:97:4:103:4 | { ... } | TestFinally.java:98:5:98:36 | ...; | | TestFinally.java:98:5:98:14 | System.out | TestFinally.java:98:24:98:34 | "Exception" | -| TestFinally.java:98:5:98:35 | println(...) | TestFinally.java:99:5:99:15 | stmt | -| TestFinally.java:98:5:98:36 | stmt | TestFinally.java:98:5:98:14 | System.out | +| TestFinally.java:98:5:98:35 | println(...) | TestFinally.java:99:5:99:15 | if (...) | +| TestFinally.java:98:5:98:36 | ...; | TestFinally.java:98:5:98:14 | System.out | | TestFinally.java:98:24:98:34 | "Exception" | TestFinally.java:98:5:98:35 | println(...) | -| TestFinally.java:99:5:99:15 | stmt | TestFinally.java:99:9:99:9 | z | +| TestFinally.java:99:5:99:15 | if (...) | TestFinally.java:99:9:99:9 | z | | TestFinally.java:99:9:99:9 | z | TestFinally.java:99:14:99:14 | 1 | -| TestFinally.java:99:9:99:14 | ... == ... | TestFinally.java:100:5:102:5 | stmt | -| TestFinally.java:99:9:99:14 | ... == ... | TestFinally.java:104:4:111:4 | stmt | +| TestFinally.java:99:9:99:14 | ... == ... | TestFinally.java:100:5:102:5 | { ... } | +| TestFinally.java:99:9:99:14 | ... == ... | TestFinally.java:104:4:111:4 | { ... } | | TestFinally.java:99:14:99:14 | 1 | TestFinally.java:99:9:99:14 | ... == ... | -| TestFinally.java:100:5:102:5 | stmt | TestFinally.java:101:6:101:12 | stmt | -| TestFinally.java:101:6:101:12 | stmt | TestFinally.java:104:4:111:4 | stmt | -| TestFinally.java:104:4:111:4 | stmt | TestFinally.java:105:5:105:34 | stmt | +| TestFinally.java:100:5:102:5 | { ... } | TestFinally.java:101:6:101:12 | return ... | +| TestFinally.java:101:6:101:12 | return ... | TestFinally.java:104:4:111:4 | { ... } | +| TestFinally.java:104:4:111:4 | { ... } | TestFinally.java:105:5:105:34 | ...; | | TestFinally.java:105:5:105:14 | System.out | TestFinally.java:105:24:105:32 | "Finally" | -| TestFinally.java:105:5:105:33 | println(...) | TestFinally.java:106:5:106:15 | stmt | -| TestFinally.java:105:5:105:34 | stmt | TestFinally.java:105:5:105:14 | System.out | +| TestFinally.java:105:5:105:33 | println(...) | TestFinally.java:106:5:106:15 | if (...) | +| TestFinally.java:105:5:105:34 | ...; | TestFinally.java:105:5:105:14 | System.out | | TestFinally.java:105:24:105:32 | "Finally" | TestFinally.java:105:5:105:33 | println(...) | -| TestFinally.java:106:5:106:15 | stmt | TestFinally.java:106:9:106:9 | z | +| TestFinally.java:106:5:106:15 | if (...) | TestFinally.java:106:9:106:9 | z | | TestFinally.java:106:9:106:9 | z | TestFinally.java:106:14:106:14 | 1 | -| TestFinally.java:106:9:106:14 | ... == ... | TestFinally.java:107:5:109:5 | stmt | -| TestFinally.java:106:9:106:14 | ... == ... | TestFinally.java:110:5:110:35 | stmt | +| TestFinally.java:106:9:106:14 | ... == ... | TestFinally.java:107:5:109:5 | { ... } | +| TestFinally.java:106:9:106:14 | ... == ... | TestFinally.java:110:5:110:35 | ...; | | TestFinally.java:106:14:106:14 | 1 | TestFinally.java:106:9:106:14 | ... == ... | -| TestFinally.java:107:5:109:5 | stmt | TestFinally.java:108:6:108:12 | stmt | -| TestFinally.java:108:6:108:12 | stmt | TestFinally.java:116:3:120:3 | stmt | +| TestFinally.java:107:5:109:5 | { ... } | TestFinally.java:108:6:108:12 | return ... | +| TestFinally.java:108:6:108:12 | return ... | TestFinally.java:116:3:120:3 | { ... } | | TestFinally.java:110:5:110:14 | System.out | TestFinally.java:110:24:110:33 | "Finally2" | -| TestFinally.java:110:5:110:34 | println(...) | TestFinally.java:112:4:112:13 | stmt | -| TestFinally.java:110:5:110:34 | println(...) | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:110:5:110:35 | stmt | TestFinally.java:110:5:110:14 | System.out | +| TestFinally.java:110:5:110:34 | println(...) | TestFinally.java:112:4:112:13 | local variable declaration | +| TestFinally.java:110:5:110:34 | println(...) | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:110:5:110:35 | ...; | TestFinally.java:110:5:110:14 | System.out | | TestFinally.java:110:24:110:33 | "Finally2" | TestFinally.java:110:5:110:34 | println(...) | -| TestFinally.java:112:4:112:13 | stmt | TestFinally.java:112:12:112:12 | 1 | -| TestFinally.java:112:8:112:12 | x | TestFinally.java:113:4:113:37 | stmt | +| TestFinally.java:112:4:112:13 | local variable declaration | TestFinally.java:112:12:112:12 | 1 | +| TestFinally.java:112:8:112:12 | x | TestFinally.java:113:4:113:37 | ...; | | TestFinally.java:112:12:112:12 | 1 | TestFinally.java:112:8:112:12 | x | | TestFinally.java:113:4:113:13 | System.out | TestFinally.java:113:23:113:31 | "Error: " | -| TestFinally.java:113:4:113:36 | println(...) | TestFinally.java:114:4:114:13 | stmt | -| TestFinally.java:113:4:113:37 | stmt | TestFinally.java:113:4:113:13 | System.out | +| TestFinally.java:113:4:113:36 | println(...) | TestFinally.java:114:4:114:13 | ...; | +| TestFinally.java:113:4:113:37 | ...; | TestFinally.java:113:4:113:13 | System.out | | TestFinally.java:113:23:113:31 | "Error: " | TestFinally.java:113:35:113:35 | e | | TestFinally.java:113:23:113:35 | ... + ... | TestFinally.java:113:4:113:36 | println(...) | | TestFinally.java:113:35:113:35 | e | TestFinally.java:113:23:113:35 | ... + ... | -| TestFinally.java:114:4:114:12 | ...=... | TestFinally.java:116:3:120:3 | stmt | -| TestFinally.java:114:4:114:13 | stmt | TestFinally.java:114:8:114:8 | x | +| TestFinally.java:114:4:114:12 | ...=... | TestFinally.java:116:3:120:3 | { ... } | +| TestFinally.java:114:4:114:13 | ...; | TestFinally.java:114:8:114:8 | x | | TestFinally.java:114:8:114:8 | x | TestFinally.java:114:12:114:12 | 1 | | TestFinally.java:114:8:114:12 | ... + ... | TestFinally.java:114:4:114:12 | ...=... | | TestFinally.java:114:12:114:12 | 1 | TestFinally.java:114:8:114:12 | ... + ... | -| TestFinally.java:116:3:120:3 | stmt | TestFinally.java:117:4:117:14 | stmt | -| TestFinally.java:117:4:117:14 | stmt | TestFinally.java:117:12:117:13 | 12 | -| TestFinally.java:117:8:117:13 | y | TestFinally.java:118:4:118:33 | stmt | +| TestFinally.java:116:3:120:3 | { ... } | TestFinally.java:117:4:117:14 | local variable declaration | +| TestFinally.java:117:4:117:14 | local variable declaration | TestFinally.java:117:12:117:13 | 12 | +| TestFinally.java:117:8:117:13 | y | TestFinally.java:118:4:118:33 | ...; | | TestFinally.java:117:12:117:13 | 12 | TestFinally.java:117:8:117:13 | y | | TestFinally.java:118:4:118:13 | System.out | TestFinally.java:118:23:118:31 | "Finally" | -| TestFinally.java:118:4:118:32 | println(...) | TestFinally.java:119:4:119:13 | stmt | -| TestFinally.java:118:4:118:33 | stmt | TestFinally.java:118:4:118:13 | System.out | +| TestFinally.java:118:4:118:32 | println(...) | TestFinally.java:119:4:119:13 | ...; | +| TestFinally.java:118:4:118:33 | ...; | TestFinally.java:118:4:118:13 | System.out | | TestFinally.java:118:23:118:31 | "Finally" | TestFinally.java:118:4:118:32 | println(...) | | TestFinally.java:119:4:119:12 | ...=... | TestFinally.java:4:14:4:14 | f | -| TestFinally.java:119:4:119:12 | ...=... | TestFinally.java:121:3:121:12 | stmt | -| TestFinally.java:119:4:119:13 | stmt | TestFinally.java:119:8:119:8 | y | +| TestFinally.java:119:4:119:12 | ...=... | TestFinally.java:121:3:121:12 | ...; | +| TestFinally.java:119:4:119:13 | ...; | TestFinally.java:119:8:119:8 | y | | TestFinally.java:119:8:119:8 | y | TestFinally.java:119:12:119:12 | 1 | | TestFinally.java:119:8:119:12 | ... + ... | TestFinally.java:119:4:119:12 | ...=... | | TestFinally.java:119:12:119:12 | 1 | TestFinally.java:119:8:119:12 | ... + ... | -| TestFinally.java:121:3:121:11 | ...=... | TestFinally.java:123:3:146:3 | stmt | -| TestFinally.java:121:3:121:12 | stmt | TestFinally.java:121:7:121:7 | z | +| TestFinally.java:121:3:121:11 | ...=... | TestFinally.java:123:3:146:3 | try ... | +| TestFinally.java:121:3:121:12 | ...; | TestFinally.java:121:7:121:7 | z | | TestFinally.java:121:7:121:7 | z | TestFinally.java:121:11:121:11 | 1 | | TestFinally.java:121:7:121:11 | ... + ... | TestFinally.java:121:3:121:11 | ...=... | | TestFinally.java:121:11:121:11 | 1 | TestFinally.java:121:7:121:11 | ... + ... | -| TestFinally.java:123:3:146:3 | stmt | TestFinally.java:124:3:131:3 | stmt | -| TestFinally.java:124:3:131:3 | stmt | TestFinally.java:125:4:125:30 | stmt | +| TestFinally.java:123:3:146:3 | try ... | TestFinally.java:124:3:131:3 | { ... } | +| TestFinally.java:124:3:131:3 | { ... } | TestFinally.java:125:4:125:30 | ...; | | TestFinally.java:125:4:125:13 | System.out | TestFinally.java:125:23:125:28 | "Try1" | -| TestFinally.java:125:4:125:29 | println(...) | TestFinally.java:126:4:126:14 | stmt | -| TestFinally.java:125:4:125:29 | println(...) | TestFinally.java:131:5:131:24 | stmt | -| TestFinally.java:125:4:125:29 | println(...) | TestFinally.java:139:3:146:3 | stmt | -| TestFinally.java:125:4:125:30 | stmt | TestFinally.java:125:4:125:13 | System.out | +| TestFinally.java:125:4:125:29 | println(...) | TestFinally.java:126:4:126:14 | if (...) | +| TestFinally.java:125:4:125:29 | println(...) | TestFinally.java:131:5:131:24 | catch (...) | +| TestFinally.java:125:4:125:29 | println(...) | TestFinally.java:139:3:146:3 | { ... } | +| TestFinally.java:125:4:125:30 | ...; | TestFinally.java:125:4:125:13 | System.out | | TestFinally.java:125:23:125:28 | "Try1" | TestFinally.java:125:4:125:29 | println(...) | -| TestFinally.java:126:4:126:14 | stmt | TestFinally.java:126:8:126:8 | z | +| TestFinally.java:126:4:126:14 | if (...) | TestFinally.java:126:8:126:8 | z | | TestFinally.java:126:8:126:8 | z | TestFinally.java:126:13:126:13 | 1 | -| TestFinally.java:126:8:126:13 | ... == ... | TestFinally.java:127:4:129:4 | stmt | -| TestFinally.java:126:8:126:13 | ... == ... | TestFinally.java:130:4:130:30 | stmt | +| TestFinally.java:126:8:126:13 | ... == ... | TestFinally.java:127:4:129:4 | { ... } | +| TestFinally.java:126:8:126:13 | ... == ... | TestFinally.java:130:4:130:30 | ...; | | TestFinally.java:126:13:126:13 | 1 | TestFinally.java:126:8:126:13 | ... == ... | -| TestFinally.java:127:4:129:4 | stmt | TestFinally.java:128:5:128:11 | stmt | -| TestFinally.java:128:5:128:11 | stmt | TestFinally.java:139:3:146:3 | stmt | +| TestFinally.java:127:4:129:4 | { ... } | TestFinally.java:128:5:128:11 | return ... | +| TestFinally.java:128:5:128:11 | return ... | TestFinally.java:139:3:146:3 | { ... } | | TestFinally.java:130:4:130:13 | System.out | TestFinally.java:130:23:130:28 | "Try2" | -| TestFinally.java:130:4:130:29 | println(...) | TestFinally.java:131:5:131:24 | stmt | -| TestFinally.java:130:4:130:29 | println(...) | TestFinally.java:139:3:146:3 | stmt | -| TestFinally.java:130:4:130:30 | stmt | TestFinally.java:130:4:130:13 | System.out | +| TestFinally.java:130:4:130:29 | println(...) | TestFinally.java:131:5:131:24 | catch (...) | +| TestFinally.java:130:4:130:29 | println(...) | TestFinally.java:139:3:146:3 | { ... } | +| TestFinally.java:130:4:130:30 | ...; | TestFinally.java:130:4:130:13 | System.out | | TestFinally.java:130:23:130:28 | "Try2" | TestFinally.java:130:4:130:29 | println(...) | -| TestFinally.java:131:5:131:24 | stmt | TestFinally.java:131:22:131:23 | ex | -| TestFinally.java:131:22:131:23 | ex | TestFinally.java:132:3:138:3 | stmt | -| TestFinally.java:132:3:138:3 | stmt | TestFinally.java:133:4:133:35 | stmt | +| TestFinally.java:131:5:131:24 | catch (...) | TestFinally.java:131:22:131:23 | ex | +| TestFinally.java:131:22:131:23 | ex | TestFinally.java:132:3:138:3 | { ... } | +| TestFinally.java:132:3:138:3 | { ... } | TestFinally.java:133:4:133:35 | ...; | | TestFinally.java:133:4:133:13 | System.out | TestFinally.java:133:23:133:33 | "Exception" | -| TestFinally.java:133:4:133:34 | println(...) | TestFinally.java:134:4:134:14 | stmt | -| TestFinally.java:133:4:133:35 | stmt | TestFinally.java:133:4:133:13 | System.out | +| TestFinally.java:133:4:133:34 | println(...) | TestFinally.java:134:4:134:14 | if (...) | +| TestFinally.java:133:4:133:35 | ...; | TestFinally.java:133:4:133:13 | System.out | | TestFinally.java:133:23:133:33 | "Exception" | TestFinally.java:133:4:133:34 | println(...) | -| TestFinally.java:134:4:134:14 | stmt | TestFinally.java:134:8:134:8 | z | +| TestFinally.java:134:4:134:14 | if (...) | TestFinally.java:134:8:134:8 | z | | TestFinally.java:134:8:134:8 | z | TestFinally.java:134:13:134:13 | 1 | -| TestFinally.java:134:8:134:13 | ... == ... | TestFinally.java:135:4:137:4 | stmt | -| TestFinally.java:134:8:134:13 | ... == ... | TestFinally.java:139:3:146:3 | stmt | +| TestFinally.java:134:8:134:13 | ... == ... | TestFinally.java:135:4:137:4 | { ... } | +| TestFinally.java:134:8:134:13 | ... == ... | TestFinally.java:139:3:146:3 | { ... } | | TestFinally.java:134:13:134:13 | 1 | TestFinally.java:134:8:134:13 | ... == ... | -| TestFinally.java:135:4:137:4 | stmt | TestFinally.java:136:5:136:11 | stmt | -| TestFinally.java:136:5:136:11 | stmt | TestFinally.java:139:3:146:3 | stmt | -| TestFinally.java:139:3:146:3 | stmt | TestFinally.java:140:4:140:33 | stmt | +| TestFinally.java:135:4:137:4 | { ... } | TestFinally.java:136:5:136:11 | return ... | +| TestFinally.java:136:5:136:11 | return ... | TestFinally.java:139:3:146:3 | { ... } | +| TestFinally.java:139:3:146:3 | { ... } | TestFinally.java:140:4:140:33 | ...; | | TestFinally.java:140:4:140:13 | System.out | TestFinally.java:140:23:140:31 | "Finally" | -| TestFinally.java:140:4:140:32 | println(...) | TestFinally.java:141:4:141:14 | stmt | -| TestFinally.java:140:4:140:33 | stmt | TestFinally.java:140:4:140:13 | System.out | +| TestFinally.java:140:4:140:32 | println(...) | TestFinally.java:141:4:141:14 | if (...) | +| TestFinally.java:140:4:140:33 | ...; | TestFinally.java:140:4:140:13 | System.out | | TestFinally.java:140:23:140:31 | "Finally" | TestFinally.java:140:4:140:32 | println(...) | -| TestFinally.java:141:4:141:14 | stmt | TestFinally.java:141:8:141:8 | z | +| TestFinally.java:141:4:141:14 | if (...) | TestFinally.java:141:8:141:8 | z | | TestFinally.java:141:8:141:8 | z | TestFinally.java:141:13:141:13 | 1 | -| TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:142:4:144:4 | stmt | -| TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:145:4:145:34 | stmt | +| TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:142:4:144:4 | { ... } | +| TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:145:4:145:34 | ...; | | TestFinally.java:141:13:141:13 | 1 | TestFinally.java:141:8:141:13 | ... == ... | -| TestFinally.java:142:4:144:4 | stmt | TestFinally.java:143:5:143:11 | stmt | -| TestFinally.java:143:5:143:11 | stmt | TestFinally.java:4:14:4:14 | f | +| TestFinally.java:142:4:144:4 | { ... } | TestFinally.java:143:5:143:11 | return ... | +| TestFinally.java:143:5:143:11 | return ... | TestFinally.java:4:14:4:14 | f | | TestFinally.java:145:4:145:13 | System.out | TestFinally.java:145:23:145:32 | "Finally2" | | TestFinally.java:145:4:145:33 | println(...) | TestFinally.java:4:14:4:14 | f | -| TestFinally.java:145:4:145:33 | println(...) | TestFinally.java:148:3:148:12 | stmt | -| TestFinally.java:145:4:145:34 | stmt | TestFinally.java:145:4:145:13 | System.out | +| TestFinally.java:145:4:145:33 | println(...) | TestFinally.java:148:3:148:12 | ...; | +| TestFinally.java:145:4:145:34 | ...; | TestFinally.java:145:4:145:13 | System.out | | TestFinally.java:145:23:145:32 | "Finally2" | TestFinally.java:145:4:145:33 | println(...) | | TestFinally.java:148:3:148:11 | ...=... | TestFinally.java:4:14:4:14 | f | -| TestFinally.java:148:3:148:12 | stmt | TestFinally.java:148:7:148:7 | z | +| TestFinally.java:148:3:148:12 | ...; | TestFinally.java:148:7:148:7 | z | | TestFinally.java:148:7:148:7 | z | TestFinally.java:148:11:148:11 | 2 | | TestFinally.java:148:7:148:11 | ... + ... | TestFinally.java:148:3:148:11 | ...=... | | TestFinally.java:148:11:148:11 | 2 | TestFinally.java:148:7:148:11 | ... + ... | diff --git a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/FalseSuccessors.expected index c2e6008f52d..1de80850858 100644 --- a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/FalseSuccessors.expected @@ -1,6 +1,6 @@ -| TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | TestFinallyBreakContinue.java:16:5:18:5 | stmt | -| TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | TestFinallyBreakContinue.java:25:5:27:5 | stmt | -| TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | TestFinallyBreakContinue.java:44:6:46:6 | stmt | -| TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | TestFinallyBreakContinue.java:53:6:55:6 | stmt | -| TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | TestFinallyBreakContinue.java:82:7:84:7 | stmt | -| TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | TestFinallyBreakContinue.java:91:7:93:7 | stmt | +| TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | TestFinallyBreakContinue.java:16:5:18:5 | { ... } | +| TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | TestFinallyBreakContinue.java:25:5:27:5 | { ... } | +| TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | TestFinallyBreakContinue.java:44:6:46:6 | { ... } | +| TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | TestFinallyBreakContinue.java:53:6:55:6 | { ... } | +| TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | TestFinallyBreakContinue.java:82:7:84:7 | { ... } | +| TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | TestFinallyBreakContinue.java:91:7:93:7 | { ... } | diff --git a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected index 9ef9bab4172..2beed591041 100644 --- a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected @@ -1,141 +1,141 @@ -| TestFinallyBreakContinue.java:3:14:3:37 | stmt | TestFinallyBreakContinue.java:3:14:3:37 | super(...) | | TestFinallyBreakContinue.java:3:14:3:37 | super(...) | TestFinallyBreakContinue.java:3:14:3:37 | TestFinallyBreakContinue | -| TestFinallyBreakContinue.java:5:2:107:2 | stmt | TestFinallyBreakContinue.java:6:3:6:12 | stmt | -| TestFinallyBreakContinue.java:6:3:6:12 | stmt | TestFinallyBreakContinue.java:6:11:6:11 | 1 | -| TestFinallyBreakContinue.java:6:7:6:11 | x | TestFinallyBreakContinue.java:7:3:8:10 | stmt | +| TestFinallyBreakContinue.java:3:14:3:37 | { ... } | TestFinallyBreakContinue.java:3:14:3:37 | super(...) | +| TestFinallyBreakContinue.java:5:2:107:2 | { ... } | TestFinallyBreakContinue.java:6:3:6:12 | local variable declaration | +| TestFinallyBreakContinue.java:6:3:6:12 | local variable declaration | TestFinallyBreakContinue.java:6:11:6:11 | 1 | +| TestFinallyBreakContinue.java:6:7:6:11 | x | TestFinallyBreakContinue.java:7:3:8:10 | labeled statement | | TestFinallyBreakContinue.java:6:11:6:11 | 1 | TestFinallyBreakContinue.java:6:7:6:11 | x | -| TestFinallyBreakContinue.java:7:3:8:10 | stmt | TestFinallyBreakContinue.java:8:3:8:10 | stmt | -| TestFinallyBreakContinue.java:8:3:8:10 | stmt | TestFinallyBreakContinue.java:9:3:32:3 | stmt | -| TestFinallyBreakContinue.java:9:3:32:3 | stmt | TestFinallyBreakContinue.java:10:4:31:4 | stmt | -| TestFinallyBreakContinue.java:10:4:31:4 | stmt | TestFinallyBreakContinue.java:11:4:19:4 | stmt | -| TestFinallyBreakContinue.java:11:4:19:4 | stmt | TestFinallyBreakContinue.java:12:5:12:15 | stmt | -| TestFinallyBreakContinue.java:12:5:12:15 | stmt | TestFinallyBreakContinue.java:12:9:12:9 | x | +| TestFinallyBreakContinue.java:7:3:8:10 | labeled statement | TestFinallyBreakContinue.java:8:3:8:10 | for (...) | +| TestFinallyBreakContinue.java:8:3:8:10 | for (...) | TestFinallyBreakContinue.java:9:3:32:3 | { ... } | +| TestFinallyBreakContinue.java:9:3:32:3 | { ... } | TestFinallyBreakContinue.java:10:4:31:4 | try ... | +| TestFinallyBreakContinue.java:10:4:31:4 | try ... | TestFinallyBreakContinue.java:11:4:19:4 | { ... } | +| TestFinallyBreakContinue.java:11:4:19:4 | { ... } | TestFinallyBreakContinue.java:12:5:12:15 | if (...) | +| TestFinallyBreakContinue.java:12:5:12:15 | if (...) | TestFinallyBreakContinue.java:12:9:12:9 | x | | TestFinallyBreakContinue.java:12:9:12:9 | x | TestFinallyBreakContinue.java:12:14:12:14 | 1 | -| TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | TestFinallyBreakContinue.java:13:5:15:5 | stmt | -| TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | TestFinallyBreakContinue.java:16:5:18:5 | stmt | +| TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | TestFinallyBreakContinue.java:13:5:15:5 | { ... } | +| TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | TestFinallyBreakContinue.java:16:5:18:5 | { ... } | | TestFinallyBreakContinue.java:12:14:12:14 | 1 | TestFinallyBreakContinue.java:12:9:12:14 | ... == ... | -| TestFinallyBreakContinue.java:13:5:15:5 | stmt | TestFinallyBreakContinue.java:14:6:14:11 | stmt | -| TestFinallyBreakContinue.java:14:6:14:11 | stmt | TestFinallyBreakContinue.java:29:4:31:4 | stmt | -| TestFinallyBreakContinue.java:16:5:18:5 | stmt | TestFinallyBreakContinue.java:17:6:17:14 | stmt | -| TestFinallyBreakContinue.java:17:6:17:14 | stmt | TestFinallyBreakContinue.java:29:4:31:4 | stmt | -| TestFinallyBreakContinue.java:19:6:19:24 | stmt | TestFinallyBreakContinue.java:19:23:19:23 | e | -| TestFinallyBreakContinue.java:19:23:19:23 | e | TestFinallyBreakContinue.java:20:4:28:4 | stmt | -| TestFinallyBreakContinue.java:20:4:28:4 | stmt | TestFinallyBreakContinue.java:21:5:21:15 | stmt | -| TestFinallyBreakContinue.java:21:5:21:15 | stmt | TestFinallyBreakContinue.java:21:9:21:9 | x | +| TestFinallyBreakContinue.java:13:5:15:5 | { ... } | TestFinallyBreakContinue.java:14:6:14:11 | break | +| TestFinallyBreakContinue.java:14:6:14:11 | break | TestFinallyBreakContinue.java:29:4:31:4 | { ... } | +| TestFinallyBreakContinue.java:16:5:18:5 | { ... } | TestFinallyBreakContinue.java:17:6:17:14 | continue | +| TestFinallyBreakContinue.java:17:6:17:14 | continue | TestFinallyBreakContinue.java:29:4:31:4 | { ... } | +| TestFinallyBreakContinue.java:19:6:19:24 | catch (...) | TestFinallyBreakContinue.java:19:23:19:23 | e | +| TestFinallyBreakContinue.java:19:23:19:23 | e | TestFinallyBreakContinue.java:20:4:28:4 | { ... } | +| TestFinallyBreakContinue.java:20:4:28:4 | { ... } | TestFinallyBreakContinue.java:21:5:21:15 | if (...) | +| TestFinallyBreakContinue.java:21:5:21:15 | if (...) | TestFinallyBreakContinue.java:21:9:21:9 | x | | TestFinallyBreakContinue.java:21:9:21:9 | x | TestFinallyBreakContinue.java:21:14:21:14 | 1 | -| TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | TestFinallyBreakContinue.java:22:5:24:5 | stmt | -| TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | TestFinallyBreakContinue.java:25:5:27:5 | stmt | +| TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | TestFinallyBreakContinue.java:22:5:24:5 | { ... } | +| TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | TestFinallyBreakContinue.java:25:5:27:5 | { ... } | | TestFinallyBreakContinue.java:21:14:21:14 | 1 | TestFinallyBreakContinue.java:21:9:21:14 | ... == ... | -| TestFinallyBreakContinue.java:22:5:24:5 | stmt | TestFinallyBreakContinue.java:23:6:23:11 | stmt | -| TestFinallyBreakContinue.java:23:6:23:11 | stmt | TestFinallyBreakContinue.java:29:4:31:4 | stmt | -| TestFinallyBreakContinue.java:25:5:27:5 | stmt | TestFinallyBreakContinue.java:26:6:26:14 | stmt | -| TestFinallyBreakContinue.java:26:6:26:14 | stmt | TestFinallyBreakContinue.java:29:4:31:4 | stmt | -| TestFinallyBreakContinue.java:29:4:31:4 | stmt | TestFinallyBreakContinue.java:30:5:30:34 | stmt | +| TestFinallyBreakContinue.java:22:5:24:5 | { ... } | TestFinallyBreakContinue.java:23:6:23:11 | break | +| TestFinallyBreakContinue.java:23:6:23:11 | break | TestFinallyBreakContinue.java:29:4:31:4 | { ... } | +| TestFinallyBreakContinue.java:25:5:27:5 | { ... } | TestFinallyBreakContinue.java:26:6:26:14 | continue | +| TestFinallyBreakContinue.java:26:6:26:14 | continue | TestFinallyBreakContinue.java:29:4:31:4 | { ... } | +| TestFinallyBreakContinue.java:29:4:31:4 | { ... } | TestFinallyBreakContinue.java:30:5:30:34 | ...; | | TestFinallyBreakContinue.java:30:5:30:14 | System.out | TestFinallyBreakContinue.java:30:24:30:32 | "finally" | -| TestFinallyBreakContinue.java:30:5:30:33 | println(...) | TestFinallyBreakContinue.java:9:3:32:3 | stmt | -| TestFinallyBreakContinue.java:30:5:30:33 | println(...) | TestFinallyBreakContinue.java:34:3:34:14 | stmt | -| TestFinallyBreakContinue.java:30:5:30:34 | stmt | TestFinallyBreakContinue.java:30:5:30:14 | System.out | +| TestFinallyBreakContinue.java:30:5:30:33 | println(...) | TestFinallyBreakContinue.java:9:3:32:3 | { ... } | +| TestFinallyBreakContinue.java:30:5:30:33 | println(...) | TestFinallyBreakContinue.java:34:3:34:14 | while (...) | +| TestFinallyBreakContinue.java:30:5:30:34 | ...; | TestFinallyBreakContinue.java:30:5:30:14 | System.out | | TestFinallyBreakContinue.java:30:24:30:32 | "finally" | TestFinallyBreakContinue.java:30:5:30:33 | println(...) | -| TestFinallyBreakContinue.java:34:3:34:14 | stmt | TestFinallyBreakContinue.java:34:10:34:13 | true | -| TestFinallyBreakContinue.java:34:10:34:13 | true | TestFinallyBreakContinue.java:35:3:67:3 | stmt | -| TestFinallyBreakContinue.java:35:3:67:3 | stmt | TestFinallyBreakContinue.java:36:4:66:4 | stmt | -| TestFinallyBreakContinue.java:36:4:66:4 | stmt | TestFinallyBreakContinue.java:37:4:60:4 | stmt | -| TestFinallyBreakContinue.java:37:4:60:4 | stmt | TestFinallyBreakContinue.java:38:5:59:5 | stmt | -| TestFinallyBreakContinue.java:38:5:59:5 | stmt | TestFinallyBreakContinue.java:39:5:47:5 | stmt | -| TestFinallyBreakContinue.java:39:5:47:5 | stmt | TestFinallyBreakContinue.java:40:6:40:16 | stmt | -| TestFinallyBreakContinue.java:40:6:40:16 | stmt | TestFinallyBreakContinue.java:40:10:40:10 | x | +| TestFinallyBreakContinue.java:34:3:34:14 | while (...) | TestFinallyBreakContinue.java:34:10:34:13 | true | +| TestFinallyBreakContinue.java:34:10:34:13 | true | TestFinallyBreakContinue.java:35:3:67:3 | { ... } | +| TestFinallyBreakContinue.java:35:3:67:3 | { ... } | TestFinallyBreakContinue.java:36:4:66:4 | try ... | +| TestFinallyBreakContinue.java:36:4:66:4 | try ... | TestFinallyBreakContinue.java:37:4:60:4 | { ... } | +| TestFinallyBreakContinue.java:37:4:60:4 | { ... } | TestFinallyBreakContinue.java:38:5:59:5 | try ... | +| TestFinallyBreakContinue.java:38:5:59:5 | try ... | TestFinallyBreakContinue.java:39:5:47:5 | { ... } | +| TestFinallyBreakContinue.java:39:5:47:5 | { ... } | TestFinallyBreakContinue.java:40:6:40:16 | if (...) | +| TestFinallyBreakContinue.java:40:6:40:16 | if (...) | TestFinallyBreakContinue.java:40:10:40:10 | x | | TestFinallyBreakContinue.java:40:10:40:10 | x | TestFinallyBreakContinue.java:40:15:40:15 | 1 | -| TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | TestFinallyBreakContinue.java:41:6:43:6 | stmt | -| TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | TestFinallyBreakContinue.java:44:6:46:6 | stmt | +| TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | TestFinallyBreakContinue.java:41:6:43:6 | { ... } | +| TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | TestFinallyBreakContinue.java:44:6:46:6 | { ... } | | TestFinallyBreakContinue.java:40:15:40:15 | 1 | TestFinallyBreakContinue.java:40:10:40:15 | ... == ... | -| TestFinallyBreakContinue.java:41:6:43:6 | stmt | TestFinallyBreakContinue.java:42:7:42:12 | stmt | -| TestFinallyBreakContinue.java:42:7:42:12 | stmt | TestFinallyBreakContinue.java:57:5:59:5 | stmt | -| TestFinallyBreakContinue.java:44:6:46:6 | stmt | TestFinallyBreakContinue.java:45:7:45:15 | stmt | -| TestFinallyBreakContinue.java:45:7:45:15 | stmt | TestFinallyBreakContinue.java:57:5:59:5 | stmt | -| TestFinallyBreakContinue.java:47:7:47:25 | stmt | TestFinallyBreakContinue.java:47:24:47:24 | e | -| TestFinallyBreakContinue.java:47:24:47:24 | e | TestFinallyBreakContinue.java:48:5:56:5 | stmt | -| TestFinallyBreakContinue.java:48:5:56:5 | stmt | TestFinallyBreakContinue.java:49:6:49:16 | stmt | -| TestFinallyBreakContinue.java:49:6:49:16 | stmt | TestFinallyBreakContinue.java:49:10:49:10 | x | +| TestFinallyBreakContinue.java:41:6:43:6 | { ... } | TestFinallyBreakContinue.java:42:7:42:12 | break | +| TestFinallyBreakContinue.java:42:7:42:12 | break | TestFinallyBreakContinue.java:57:5:59:5 | { ... } | +| TestFinallyBreakContinue.java:44:6:46:6 | { ... } | TestFinallyBreakContinue.java:45:7:45:15 | continue | +| TestFinallyBreakContinue.java:45:7:45:15 | continue | TestFinallyBreakContinue.java:57:5:59:5 | { ... } | +| TestFinallyBreakContinue.java:47:7:47:25 | catch (...) | TestFinallyBreakContinue.java:47:24:47:24 | e | +| TestFinallyBreakContinue.java:47:24:47:24 | e | TestFinallyBreakContinue.java:48:5:56:5 | { ... } | +| TestFinallyBreakContinue.java:48:5:56:5 | { ... } | TestFinallyBreakContinue.java:49:6:49:16 | if (...) | +| TestFinallyBreakContinue.java:49:6:49:16 | if (...) | TestFinallyBreakContinue.java:49:10:49:10 | x | | TestFinallyBreakContinue.java:49:10:49:10 | x | TestFinallyBreakContinue.java:49:15:49:15 | 1 | -| TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | TestFinallyBreakContinue.java:50:6:52:6 | stmt | -| TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | TestFinallyBreakContinue.java:53:6:55:6 | stmt | +| TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | TestFinallyBreakContinue.java:50:6:52:6 | { ... } | +| TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | TestFinallyBreakContinue.java:53:6:55:6 | { ... } | | TestFinallyBreakContinue.java:49:15:49:15 | 1 | TestFinallyBreakContinue.java:49:10:49:15 | ... == ... | -| TestFinallyBreakContinue.java:50:6:52:6 | stmt | TestFinallyBreakContinue.java:51:7:51:12 | stmt | -| TestFinallyBreakContinue.java:51:7:51:12 | stmt | TestFinallyBreakContinue.java:57:5:59:5 | stmt | -| TestFinallyBreakContinue.java:53:6:55:6 | stmt | TestFinallyBreakContinue.java:54:7:54:15 | stmt | -| TestFinallyBreakContinue.java:54:7:54:15 | stmt | TestFinallyBreakContinue.java:57:5:59:5 | stmt | -| TestFinallyBreakContinue.java:57:5:59:5 | stmt | TestFinallyBreakContinue.java:58:6:58:35 | stmt | +| TestFinallyBreakContinue.java:50:6:52:6 | { ... } | TestFinallyBreakContinue.java:51:7:51:12 | break | +| TestFinallyBreakContinue.java:51:7:51:12 | break | TestFinallyBreakContinue.java:57:5:59:5 | { ... } | +| TestFinallyBreakContinue.java:53:6:55:6 | { ... } | TestFinallyBreakContinue.java:54:7:54:15 | continue | +| TestFinallyBreakContinue.java:54:7:54:15 | continue | TestFinallyBreakContinue.java:57:5:59:5 | { ... } | +| TestFinallyBreakContinue.java:57:5:59:5 | { ... } | TestFinallyBreakContinue.java:58:6:58:35 | ...; | | TestFinallyBreakContinue.java:58:6:58:15 | System.out | TestFinallyBreakContinue.java:58:25:58:33 | "finally" | -| TestFinallyBreakContinue.java:58:6:58:34 | println(...) | TestFinallyBreakContinue.java:60:6:60:24 | stmt | -| TestFinallyBreakContinue.java:58:6:58:34 | println(...) | TestFinallyBreakContinue.java:64:4:66:4 | stmt | -| TestFinallyBreakContinue.java:58:6:58:35 | stmt | TestFinallyBreakContinue.java:58:6:58:15 | System.out | +| TestFinallyBreakContinue.java:58:6:58:34 | println(...) | TestFinallyBreakContinue.java:60:6:60:24 | catch (...) | +| TestFinallyBreakContinue.java:58:6:58:34 | println(...) | TestFinallyBreakContinue.java:64:4:66:4 | { ... } | +| TestFinallyBreakContinue.java:58:6:58:35 | ...; | TestFinallyBreakContinue.java:58:6:58:15 | System.out | | TestFinallyBreakContinue.java:58:25:58:33 | "finally" | TestFinallyBreakContinue.java:58:6:58:34 | println(...) | -| TestFinallyBreakContinue.java:60:6:60:24 | stmt | TestFinallyBreakContinue.java:60:23:60:23 | e | -| TestFinallyBreakContinue.java:60:23:60:23 | e | TestFinallyBreakContinue.java:61:4:63:4 | stmt | -| TestFinallyBreakContinue.java:61:4:63:4 | stmt | TestFinallyBreakContinue.java:62:5:62:36 | stmt | +| TestFinallyBreakContinue.java:60:6:60:24 | catch (...) | TestFinallyBreakContinue.java:60:23:60:23 | e | +| TestFinallyBreakContinue.java:60:23:60:23 | e | TestFinallyBreakContinue.java:61:4:63:4 | { ... } | +| TestFinallyBreakContinue.java:61:4:63:4 | { ... } | TestFinallyBreakContinue.java:62:5:62:36 | ...; | | TestFinallyBreakContinue.java:62:5:62:14 | System.out | TestFinallyBreakContinue.java:62:24:62:34 | "Exception" | -| TestFinallyBreakContinue.java:62:5:62:35 | println(...) | TestFinallyBreakContinue.java:64:4:66:4 | stmt | -| TestFinallyBreakContinue.java:62:5:62:36 | stmt | TestFinallyBreakContinue.java:62:5:62:14 | System.out | +| TestFinallyBreakContinue.java:62:5:62:35 | println(...) | TestFinallyBreakContinue.java:64:4:66:4 | { ... } | +| TestFinallyBreakContinue.java:62:5:62:36 | ...; | TestFinallyBreakContinue.java:62:5:62:14 | System.out | | TestFinallyBreakContinue.java:62:24:62:34 | "Exception" | TestFinallyBreakContinue.java:62:5:62:35 | println(...) | -| TestFinallyBreakContinue.java:64:4:66:4 | stmt | TestFinallyBreakContinue.java:65:5:65:34 | stmt | +| TestFinallyBreakContinue.java:64:4:66:4 | { ... } | TestFinallyBreakContinue.java:65:5:65:34 | ...; | | TestFinallyBreakContinue.java:65:5:65:14 | System.out | TestFinallyBreakContinue.java:65:24:65:32 | "finally" | | TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:4:14:4:14 | f | | TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:34:10:34:13 | true | -| TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:69:3:106:17 | stmt | -| TestFinallyBreakContinue.java:65:5:65:34 | stmt | TestFinallyBreakContinue.java:65:5:65:14 | System.out | +| TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:69:3:106:17 | labeled statement | +| TestFinallyBreakContinue.java:65:5:65:34 | ...; | TestFinallyBreakContinue.java:65:5:65:14 | System.out | | TestFinallyBreakContinue.java:65:24:65:32 | "finally" | TestFinallyBreakContinue.java:65:5:65:33 | println(...) | -| TestFinallyBreakContinue.java:69:3:106:17 | stmt | TestFinallyBreakContinue.java:70:3:106:17 | stmt | -| TestFinallyBreakContinue.java:70:3:106:17 | stmt | TestFinallyBreakContinue.java:71:3:106:3 | stmt | -| TestFinallyBreakContinue.java:71:3:106:3 | stmt | TestFinallyBreakContinue.java:72:4:105:4 | stmt | -| TestFinallyBreakContinue.java:72:4:105:4 | stmt | TestFinallyBreakContinue.java:73:4:99:4 | stmt | -| TestFinallyBreakContinue.java:73:4:99:4 | stmt | TestFinallyBreakContinue.java:74:5:74:29 | stmt | -| TestFinallyBreakContinue.java:74:5:74:29 | stmt | TestFinallyBreakContinue.java:74:26:74:27 | 20 | -| TestFinallyBreakContinue.java:74:14:74:14 | i | TestFinallyBreakContinue.java:75:5:98:5 | stmt | +| TestFinallyBreakContinue.java:69:3:106:17 | labeled statement | TestFinallyBreakContinue.java:70:3:106:17 | do ... while (...) | +| TestFinallyBreakContinue.java:70:3:106:17 | do ... while (...) | TestFinallyBreakContinue.java:71:3:106:3 | { ... } | +| TestFinallyBreakContinue.java:71:3:106:3 | { ... } | TestFinallyBreakContinue.java:72:4:105:4 | try ... | +| TestFinallyBreakContinue.java:72:4:105:4 | try ... | TestFinallyBreakContinue.java:73:4:99:4 | { ... } | +| TestFinallyBreakContinue.java:73:4:99:4 | { ... } | TestFinallyBreakContinue.java:74:5:74:29 | for (... : ...) | +| TestFinallyBreakContinue.java:74:5:74:29 | for (... : ...) | TestFinallyBreakContinue.java:74:26:74:27 | 20 | +| TestFinallyBreakContinue.java:74:14:74:14 | i | TestFinallyBreakContinue.java:75:5:98:5 | { ... } | | TestFinallyBreakContinue.java:74:18:74:28 | new int[] | TestFinallyBreakContinue.java:74:14:74:14 | i | -| TestFinallyBreakContinue.java:74:18:74:28 | new int[] | TestFinallyBreakContinue.java:103:4:105:4 | stmt | +| TestFinallyBreakContinue.java:74:18:74:28 | new int[] | TestFinallyBreakContinue.java:103:4:105:4 | { ... } | | TestFinallyBreakContinue.java:74:26:74:27 | 20 | TestFinallyBreakContinue.java:74:18:74:28 | new int[] | -| TestFinallyBreakContinue.java:75:5:98:5 | stmt | TestFinallyBreakContinue.java:76:6:97:6 | stmt | -| TestFinallyBreakContinue.java:76:6:97:6 | stmt | TestFinallyBreakContinue.java:77:6:85:6 | stmt | -| TestFinallyBreakContinue.java:77:6:85:6 | stmt | TestFinallyBreakContinue.java:78:7:78:17 | stmt | -| TestFinallyBreakContinue.java:78:7:78:17 | stmt | TestFinallyBreakContinue.java:78:11:78:11 | x | +| TestFinallyBreakContinue.java:75:5:98:5 | { ... } | TestFinallyBreakContinue.java:76:6:97:6 | try ... | +| TestFinallyBreakContinue.java:76:6:97:6 | try ... | TestFinallyBreakContinue.java:77:6:85:6 | { ... } | +| TestFinallyBreakContinue.java:77:6:85:6 | { ... } | TestFinallyBreakContinue.java:78:7:78:17 | if (...) | +| TestFinallyBreakContinue.java:78:7:78:17 | if (...) | TestFinallyBreakContinue.java:78:11:78:11 | x | | TestFinallyBreakContinue.java:78:11:78:11 | x | TestFinallyBreakContinue.java:78:16:78:16 | 1 | -| TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | TestFinallyBreakContinue.java:79:7:81:7 | stmt | -| TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | TestFinallyBreakContinue.java:82:7:84:7 | stmt | +| TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | TestFinallyBreakContinue.java:79:7:81:7 | { ... } | +| TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | TestFinallyBreakContinue.java:82:7:84:7 | { ... } | | TestFinallyBreakContinue.java:78:16:78:16 | 1 | TestFinallyBreakContinue.java:78:11:78:16 | ... == ... | -| TestFinallyBreakContinue.java:79:7:81:7 | stmt | TestFinallyBreakContinue.java:80:8:80:13 | stmt | -| TestFinallyBreakContinue.java:80:8:80:13 | stmt | TestFinallyBreakContinue.java:95:6:97:6 | stmt | -| TestFinallyBreakContinue.java:82:7:84:7 | stmt | TestFinallyBreakContinue.java:83:8:83:16 | stmt | -| TestFinallyBreakContinue.java:83:8:83:16 | stmt | TestFinallyBreakContinue.java:95:6:97:6 | stmt | -| TestFinallyBreakContinue.java:85:8:85:26 | stmt | TestFinallyBreakContinue.java:85:25:85:25 | e | -| TestFinallyBreakContinue.java:85:25:85:25 | e | TestFinallyBreakContinue.java:86:6:94:6 | stmt | -| TestFinallyBreakContinue.java:86:6:94:6 | stmt | TestFinallyBreakContinue.java:87:7:87:17 | stmt | -| TestFinallyBreakContinue.java:87:7:87:17 | stmt | TestFinallyBreakContinue.java:87:11:87:11 | x | +| TestFinallyBreakContinue.java:79:7:81:7 | { ... } | TestFinallyBreakContinue.java:80:8:80:13 | break | +| TestFinallyBreakContinue.java:80:8:80:13 | break | TestFinallyBreakContinue.java:95:6:97:6 | { ... } | +| TestFinallyBreakContinue.java:82:7:84:7 | { ... } | TestFinallyBreakContinue.java:83:8:83:16 | continue | +| TestFinallyBreakContinue.java:83:8:83:16 | continue | TestFinallyBreakContinue.java:95:6:97:6 | { ... } | +| TestFinallyBreakContinue.java:85:8:85:26 | catch (...) | TestFinallyBreakContinue.java:85:25:85:25 | e | +| TestFinallyBreakContinue.java:85:25:85:25 | e | TestFinallyBreakContinue.java:86:6:94:6 | { ... } | +| TestFinallyBreakContinue.java:86:6:94:6 | { ... } | TestFinallyBreakContinue.java:87:7:87:17 | if (...) | +| TestFinallyBreakContinue.java:87:7:87:17 | if (...) | TestFinallyBreakContinue.java:87:11:87:11 | x | | TestFinallyBreakContinue.java:87:11:87:11 | x | TestFinallyBreakContinue.java:87:16:87:16 | 1 | -| TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | TestFinallyBreakContinue.java:88:7:90:7 | stmt | -| TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | TestFinallyBreakContinue.java:91:7:93:7 | stmt | +| TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | TestFinallyBreakContinue.java:88:7:90:7 | { ... } | +| TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | TestFinallyBreakContinue.java:91:7:93:7 | { ... } | | TestFinallyBreakContinue.java:87:16:87:16 | 1 | TestFinallyBreakContinue.java:87:11:87:16 | ... == ... | -| TestFinallyBreakContinue.java:88:7:90:7 | stmt | TestFinallyBreakContinue.java:89:8:89:15 | stmt | -| TestFinallyBreakContinue.java:89:8:89:15 | stmt | TestFinallyBreakContinue.java:95:6:97:6 | stmt | -| TestFinallyBreakContinue.java:91:7:93:7 | stmt | TestFinallyBreakContinue.java:92:8:92:18 | stmt | -| TestFinallyBreakContinue.java:92:8:92:18 | stmt | TestFinallyBreakContinue.java:95:6:97:6 | stmt | -| TestFinallyBreakContinue.java:95:6:97:6 | stmt | TestFinallyBreakContinue.java:96:7:96:36 | stmt | +| TestFinallyBreakContinue.java:88:7:90:7 | { ... } | TestFinallyBreakContinue.java:89:8:89:15 | break | +| TestFinallyBreakContinue.java:89:8:89:15 | break | TestFinallyBreakContinue.java:95:6:97:6 | { ... } | +| TestFinallyBreakContinue.java:91:7:93:7 | { ... } | TestFinallyBreakContinue.java:92:8:92:18 | continue | +| TestFinallyBreakContinue.java:92:8:92:18 | continue | TestFinallyBreakContinue.java:95:6:97:6 | { ... } | +| TestFinallyBreakContinue.java:95:6:97:6 | { ... } | TestFinallyBreakContinue.java:96:7:96:36 | ...; | | TestFinallyBreakContinue.java:96:7:96:16 | System.out | TestFinallyBreakContinue.java:96:26:96:34 | "finally" | | TestFinallyBreakContinue.java:96:7:96:35 | println(...) | TestFinallyBreakContinue.java:74:14:74:14 | i | -| TestFinallyBreakContinue.java:96:7:96:35 | println(...) | TestFinallyBreakContinue.java:99:6:99:24 | stmt | -| TestFinallyBreakContinue.java:96:7:96:35 | println(...) | TestFinallyBreakContinue.java:103:4:105:4 | stmt | -| TestFinallyBreakContinue.java:96:7:96:36 | stmt | TestFinallyBreakContinue.java:96:7:96:16 | System.out | +| TestFinallyBreakContinue.java:96:7:96:35 | println(...) | TestFinallyBreakContinue.java:99:6:99:24 | catch (...) | +| TestFinallyBreakContinue.java:96:7:96:35 | println(...) | TestFinallyBreakContinue.java:103:4:105:4 | { ... } | +| TestFinallyBreakContinue.java:96:7:96:36 | ...; | TestFinallyBreakContinue.java:96:7:96:16 | System.out | | TestFinallyBreakContinue.java:96:26:96:34 | "finally" | TestFinallyBreakContinue.java:96:7:96:35 | println(...) | -| TestFinallyBreakContinue.java:99:6:99:24 | stmt | TestFinallyBreakContinue.java:99:23:99:23 | e | -| TestFinallyBreakContinue.java:99:23:99:23 | e | TestFinallyBreakContinue.java:100:4:102:4 | stmt | -| TestFinallyBreakContinue.java:100:4:102:4 | stmt | TestFinallyBreakContinue.java:101:5:101:36 | stmt | +| TestFinallyBreakContinue.java:99:6:99:24 | catch (...) | TestFinallyBreakContinue.java:99:23:99:23 | e | +| TestFinallyBreakContinue.java:99:23:99:23 | e | TestFinallyBreakContinue.java:100:4:102:4 | { ... } | +| TestFinallyBreakContinue.java:100:4:102:4 | { ... } | TestFinallyBreakContinue.java:101:5:101:36 | ...; | | TestFinallyBreakContinue.java:101:5:101:14 | System.out | TestFinallyBreakContinue.java:101:24:101:34 | "Exception" | -| TestFinallyBreakContinue.java:101:5:101:35 | println(...) | TestFinallyBreakContinue.java:103:4:105:4 | stmt | -| TestFinallyBreakContinue.java:101:5:101:36 | stmt | TestFinallyBreakContinue.java:101:5:101:14 | System.out | +| TestFinallyBreakContinue.java:101:5:101:35 | println(...) | TestFinallyBreakContinue.java:103:4:105:4 | { ... } | +| TestFinallyBreakContinue.java:101:5:101:36 | ...; | TestFinallyBreakContinue.java:101:5:101:14 | System.out | | TestFinallyBreakContinue.java:101:24:101:34 | "Exception" | TestFinallyBreakContinue.java:101:5:101:35 | println(...) | -| TestFinallyBreakContinue.java:103:4:105:4 | stmt | TestFinallyBreakContinue.java:104:5:104:34 | stmt | +| TestFinallyBreakContinue.java:103:4:105:4 | { ... } | TestFinallyBreakContinue.java:104:5:104:34 | ...; | | TestFinallyBreakContinue.java:104:5:104:14 | System.out | TestFinallyBreakContinue.java:104:24:104:32 | "finally" | | TestFinallyBreakContinue.java:104:5:104:33 | println(...) | TestFinallyBreakContinue.java:4:14:4:14 | f | | TestFinallyBreakContinue.java:104:5:104:33 | println(...) | TestFinallyBreakContinue.java:106:12:106:15 | true | -| TestFinallyBreakContinue.java:104:5:104:34 | stmt | TestFinallyBreakContinue.java:104:5:104:14 | System.out | +| TestFinallyBreakContinue.java:104:5:104:34 | ...; | TestFinallyBreakContinue.java:104:5:104:14 | System.out | | TestFinallyBreakContinue.java:104:24:104:32 | "finally" | TestFinallyBreakContinue.java:104:5:104:33 | println(...) | -| TestFinallyBreakContinue.java:106:12:106:15 | true | TestFinallyBreakContinue.java:71:3:106:3 | stmt | +| TestFinallyBreakContinue.java:106:12:106:15 | true | TestFinallyBreakContinue.java:71:3:106:3 | { ... } | diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestLoopBranch/FalseSuccessors.expected index f64781efc9f..266d4ab24ab 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestLoopBranch/FalseSuccessors.expected @@ -1,5 +1,5 @@ -| TestLoopBranch.java:17:12:17:17 | ... == ... | TestLoopBranch.java:19:3:22:3 | stmt | -| TestLoopBranch.java:24:10:24:15 | ... == ... | TestLoopBranch.java:31:3:31:30 | stmt | -| TestLoopBranch.java:31:19:31:24 | ... < ... | TestLoopBranch.java:37:3:37:3 | stmt | -| TestLoopBranch.java:46:7:46:13 | ... == ... | TestLoopBranch.java:51:3:51:14 | stmt | -| TestLoopBranch.java:51:7:51:13 | ... == ... | TestLoopBranch.java:56:3:60:3 | stmt | +| TestLoopBranch.java:17:12:17:17 | ... == ... | TestLoopBranch.java:19:3:22:3 | { ... } | +| TestLoopBranch.java:24:10:24:15 | ... == ... | TestLoopBranch.java:31:3:31:30 | for (...) | +| TestLoopBranch.java:31:19:31:24 | ... < ... | TestLoopBranch.java:37:3:37:3 | ; | +| TestLoopBranch.java:46:7:46:13 | ... == ... | TestLoopBranch.java:51:3:51:14 | if (...) | +| TestLoopBranch.java:51:7:51:13 | ... == ... | TestLoopBranch.java:56:3:60:3 | { ... } | diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected index d487429aff1..65617702a28 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected @@ -1,251 +1,251 @@ -| TestLoopBranch.java:3:14:3:27 | stmt | TestLoopBranch.java:4:2:4:13 | stmt | -| TestLoopBranch.java:4:2:4:13 | ...=... | TestLoopBranch.java:5:2:5:13 | stmt | -| TestLoopBranch.java:4:2:4:13 | stmt | TestLoopBranch.java:4:11:4:12 | 12 | +| TestLoopBranch.java:3:14:3:27 | { ... } | TestLoopBranch.java:4:2:4:13 | ...; | +| TestLoopBranch.java:4:2:4:13 | ...; | TestLoopBranch.java:4:11:4:12 | 12 | +| TestLoopBranch.java:4:2:4:13 | ...=... | TestLoopBranch.java:5:2:5:13 | ...; | | TestLoopBranch.java:4:11:4:12 | 12 | TestLoopBranch.java:4:2:4:13 | ...=... | +| TestLoopBranch.java:5:2:5:13 | ...; | TestLoopBranch.java:5:11:5:12 | 13 | | TestLoopBranch.java:5:2:5:13 | ...=... | TestLoopBranch.java:3:14:3:27 | | -| TestLoopBranch.java:5:2:5:13 | stmt | TestLoopBranch.java:5:11:5:12 | 13 | | TestLoopBranch.java:5:11:5:12 | 13 | TestLoopBranch.java:5:2:5:13 | ...=... | -| TestLoopBranch.java:8:2:107:2 | stmt | TestLoopBranch.java:9:3:9:12 | stmt | -| TestLoopBranch.java:9:3:9:12 | stmt | TestLoopBranch.java:9:11:9:11 | 1 | -| TestLoopBranch.java:9:7:9:11 | x | TestLoopBranch.java:10:3:10:12 | stmt | +| TestLoopBranch.java:8:2:107:2 | { ... } | TestLoopBranch.java:9:3:9:12 | local variable declaration | +| TestLoopBranch.java:9:3:9:12 | local variable declaration | TestLoopBranch.java:9:11:9:11 | 1 | +| TestLoopBranch.java:9:7:9:11 | x | TestLoopBranch.java:10:3:10:12 | local variable declaration | | TestLoopBranch.java:9:11:9:11 | 1 | TestLoopBranch.java:9:7:9:11 | x | -| TestLoopBranch.java:10:3:10:12 | stmt | TestLoopBranch.java:10:11:10:11 | 2 | -| TestLoopBranch.java:10:7:10:11 | y | TestLoopBranch.java:11:3:11:28 | stmt | +| TestLoopBranch.java:10:3:10:12 | local variable declaration | TestLoopBranch.java:10:11:10:11 | 2 | +| TestLoopBranch.java:10:7:10:11 | y | TestLoopBranch.java:11:3:11:28 | ...; | | TestLoopBranch.java:10:11:10:11 | 2 | TestLoopBranch.java:10:7:10:11 | y | | TestLoopBranch.java:11:3:11:12 | System.out | TestLoopBranch.java:11:22:11:26 | "foo" | -| TestLoopBranch.java:11:3:11:27 | println(...) | TestLoopBranch.java:13:3:17:19 | stmt | -| TestLoopBranch.java:11:3:11:28 | stmt | TestLoopBranch.java:11:3:11:12 | System.out | +| TestLoopBranch.java:11:3:11:27 | println(...) | TestLoopBranch.java:13:3:17:19 | do ... while (...) | +| TestLoopBranch.java:11:3:11:28 | ...; | TestLoopBranch.java:11:3:11:12 | System.out | | TestLoopBranch.java:11:22:11:26 | "foo" | TestLoopBranch.java:11:3:11:27 | println(...) | -| TestLoopBranch.java:13:3:17:19 | stmt | TestLoopBranch.java:14:3:17:3 | stmt | -| TestLoopBranch.java:14:3:17:3 | stmt | TestLoopBranch.java:15:4:15:29 | stmt | +| TestLoopBranch.java:13:3:17:19 | do ... while (...) | TestLoopBranch.java:14:3:17:3 | { ... } | +| TestLoopBranch.java:14:3:17:3 | { ... } | TestLoopBranch.java:15:4:15:29 | ...; | | TestLoopBranch.java:15:4:15:13 | System.out | TestLoopBranch.java:15:23:15:27 | "bar" | -| TestLoopBranch.java:15:4:15:28 | println(...) | TestLoopBranch.java:16:4:16:32 | stmt | -| TestLoopBranch.java:15:4:15:29 | stmt | TestLoopBranch.java:15:4:15:13 | System.out | +| TestLoopBranch.java:15:4:15:28 | println(...) | TestLoopBranch.java:16:4:16:32 | ...; | +| TestLoopBranch.java:15:4:15:29 | ...; | TestLoopBranch.java:15:4:15:13 | System.out | | TestLoopBranch.java:15:23:15:27 | "bar" | TestLoopBranch.java:15:4:15:28 | println(...) | | TestLoopBranch.java:16:4:16:13 | System.out | TestLoopBranch.java:16:23:16:30 | "foobar" | | TestLoopBranch.java:16:4:16:31 | println(...) | TestLoopBranch.java:17:12:17:12 | x | -| TestLoopBranch.java:16:4:16:32 | stmt | TestLoopBranch.java:16:4:16:13 | System.out | +| TestLoopBranch.java:16:4:16:32 | ...; | TestLoopBranch.java:16:4:16:13 | System.out | | TestLoopBranch.java:16:23:16:30 | "foobar" | TestLoopBranch.java:16:4:16:31 | println(...) | | TestLoopBranch.java:17:12:17:12 | x | TestLoopBranch.java:17:17:17:17 | 2 | -| TestLoopBranch.java:17:12:17:17 | ... == ... | TestLoopBranch.java:14:3:17:3 | stmt | -| TestLoopBranch.java:17:12:17:17 | ... == ... | TestLoopBranch.java:19:3:22:3 | stmt | +| TestLoopBranch.java:17:12:17:17 | ... == ... | TestLoopBranch.java:14:3:17:3 | { ... } | +| TestLoopBranch.java:17:12:17:17 | ... == ... | TestLoopBranch.java:19:3:22:3 | { ... } | | TestLoopBranch.java:17:17:17:17 | 2 | TestLoopBranch.java:17:12:17:17 | ... == ... | -| TestLoopBranch.java:19:3:22:3 | stmt | TestLoopBranch.java:20:4:20:32 | stmt | +| TestLoopBranch.java:19:3:22:3 | { ... } | TestLoopBranch.java:20:4:20:32 | ...; | | TestLoopBranch.java:20:4:20:13 | System.out | TestLoopBranch.java:20:23:20:30 | "shazam" | -| TestLoopBranch.java:20:4:20:31 | println(...) | TestLoopBranch.java:21:4:21:32 | stmt | -| TestLoopBranch.java:20:4:20:32 | stmt | TestLoopBranch.java:20:4:20:13 | System.out | +| TestLoopBranch.java:20:4:20:31 | println(...) | TestLoopBranch.java:21:4:21:32 | ...; | +| TestLoopBranch.java:20:4:20:32 | ...; | TestLoopBranch.java:20:4:20:13 | System.out | | TestLoopBranch.java:20:23:20:30 | "shazam" | TestLoopBranch.java:20:4:20:31 | println(...) | | TestLoopBranch.java:21:4:21:13 | System.out | TestLoopBranch.java:21:23:21:30 | "boogie" | -| TestLoopBranch.java:21:4:21:31 | println(...) | TestLoopBranch.java:24:3:24:16 | stmt | -| TestLoopBranch.java:21:4:21:32 | stmt | TestLoopBranch.java:21:4:21:13 | System.out | +| TestLoopBranch.java:21:4:21:31 | println(...) | TestLoopBranch.java:24:3:24:16 | while (...) | +| TestLoopBranch.java:21:4:21:32 | ...; | TestLoopBranch.java:21:4:21:13 | System.out | | TestLoopBranch.java:21:23:21:30 | "boogie" | TestLoopBranch.java:21:4:21:31 | println(...) | -| TestLoopBranch.java:24:3:24:16 | stmt | TestLoopBranch.java:24:10:24:10 | x | +| TestLoopBranch.java:24:3:24:16 | while (...) | TestLoopBranch.java:24:10:24:10 | x | | TestLoopBranch.java:24:10:24:10 | x | TestLoopBranch.java:24:15:24:15 | 1 | -| TestLoopBranch.java:24:10:24:15 | ... == ... | TestLoopBranch.java:25:3:29:3 | stmt | -| TestLoopBranch.java:24:10:24:15 | ... == ... | TestLoopBranch.java:31:3:31:30 | stmt | +| TestLoopBranch.java:24:10:24:15 | ... == ... | TestLoopBranch.java:25:3:29:3 | { ... } | +| TestLoopBranch.java:24:10:24:15 | ... == ... | TestLoopBranch.java:31:3:31:30 | for (...) | | TestLoopBranch.java:24:15:24:15 | 1 | TestLoopBranch.java:24:10:24:15 | ... == ... | -| TestLoopBranch.java:25:3:29:3 | stmt | TestLoopBranch.java:26:4:26:36 | stmt | +| TestLoopBranch.java:25:3:29:3 | { ... } | TestLoopBranch.java:26:4:26:36 | ...; | | TestLoopBranch.java:26:4:26:13 | System.out | TestLoopBranch.java:26:23:26:34 | "wonderland" | -| TestLoopBranch.java:26:4:26:35 | println(...) | TestLoopBranch.java:27:4:27:32 | stmt | -| TestLoopBranch.java:26:4:26:36 | stmt | TestLoopBranch.java:26:4:26:13 | System.out | +| TestLoopBranch.java:26:4:26:35 | println(...) | TestLoopBranch.java:27:4:27:32 | ...; | +| TestLoopBranch.java:26:4:26:36 | ...; | TestLoopBranch.java:26:4:26:13 | System.out | | TestLoopBranch.java:26:23:26:34 | "wonderland" | TestLoopBranch.java:26:4:26:35 | println(...) | | TestLoopBranch.java:27:4:27:13 | System.out | TestLoopBranch.java:27:23:27:30 | "shodan" | -| TestLoopBranch.java:27:4:27:31 | println(...) | TestLoopBranch.java:28:4:28:13 | stmt | -| TestLoopBranch.java:27:4:27:32 | stmt | TestLoopBranch.java:27:4:27:13 | System.out | +| TestLoopBranch.java:27:4:27:31 | println(...) | TestLoopBranch.java:28:4:28:13 | ...; | +| TestLoopBranch.java:27:4:27:32 | ...; | TestLoopBranch.java:27:4:27:13 | System.out | | TestLoopBranch.java:27:23:27:30 | "shodan" | TestLoopBranch.java:27:4:27:31 | println(...) | | TestLoopBranch.java:28:4:28:12 | ...=... | TestLoopBranch.java:24:10:24:10 | x | -| TestLoopBranch.java:28:4:28:13 | stmt | TestLoopBranch.java:28:8:28:8 | x | +| TestLoopBranch.java:28:4:28:13 | ...; | TestLoopBranch.java:28:8:28:8 | x | | TestLoopBranch.java:28:8:28:8 | x | TestLoopBranch.java:28:12:28:12 | 1 | | TestLoopBranch.java:28:8:28:12 | ... + ... | TestLoopBranch.java:28:4:28:12 | ...=... | | TestLoopBranch.java:28:12:28:12 | 1 | TestLoopBranch.java:28:8:28:12 | ... + ... | -| TestLoopBranch.java:31:3:31:30 | stmt | TestLoopBranch.java:31:16:31:16 | 0 | +| TestLoopBranch.java:31:3:31:30 | for (...) | TestLoopBranch.java:31:16:31:16 | 0 | | TestLoopBranch.java:31:12:31:16 | i | TestLoopBranch.java:31:19:31:19 | i | | TestLoopBranch.java:31:16:31:16 | 0 | TestLoopBranch.java:31:12:31:16 | i | | TestLoopBranch.java:31:19:31:19 | i | TestLoopBranch.java:31:23:31:24 | 10 | -| TestLoopBranch.java:31:19:31:24 | ... < ... | TestLoopBranch.java:32:3:35:3 | stmt | -| TestLoopBranch.java:31:19:31:24 | ... < ... | TestLoopBranch.java:37:3:37:3 | stmt | +| TestLoopBranch.java:31:19:31:24 | ... < ... | TestLoopBranch.java:32:3:35:3 | { ... } | +| TestLoopBranch.java:31:19:31:24 | ... < ... | TestLoopBranch.java:37:3:37:3 | ; | | TestLoopBranch.java:31:23:31:24 | 10 | TestLoopBranch.java:31:19:31:24 | ... < ... | | TestLoopBranch.java:31:27:31:27 | i | TestLoopBranch.java:31:27:31:29 | ...++ | | TestLoopBranch.java:31:27:31:29 | ...++ | TestLoopBranch.java:31:19:31:19 | i | -| TestLoopBranch.java:32:3:35:3 | stmt | TestLoopBranch.java:33:4:33:33 | stmt | +| TestLoopBranch.java:32:3:35:3 | { ... } | TestLoopBranch.java:33:4:33:33 | ...; | | TestLoopBranch.java:33:4:33:13 | System.out | TestLoopBranch.java:33:23:33:31 | "rapture" | -| TestLoopBranch.java:33:4:33:32 | println(...) | TestLoopBranch.java:34:4:34:13 | stmt | -| TestLoopBranch.java:33:4:33:33 | stmt | TestLoopBranch.java:33:4:33:13 | System.out | +| TestLoopBranch.java:33:4:33:32 | println(...) | TestLoopBranch.java:34:4:34:13 | ...; | +| TestLoopBranch.java:33:4:33:33 | ...; | TestLoopBranch.java:33:4:33:13 | System.out | | TestLoopBranch.java:33:23:33:31 | "rapture" | TestLoopBranch.java:33:4:33:32 | println(...) | | TestLoopBranch.java:34:4:34:12 | ...=... | TestLoopBranch.java:31:27:31:27 | i | -| TestLoopBranch.java:34:4:34:13 | stmt | TestLoopBranch.java:34:8:34:8 | x | +| TestLoopBranch.java:34:4:34:13 | ...; | TestLoopBranch.java:34:8:34:8 | x | | TestLoopBranch.java:34:8:34:8 | x | TestLoopBranch.java:34:12:34:12 | 2 | | TestLoopBranch.java:34:8:34:12 | ... - ... | TestLoopBranch.java:34:4:34:12 | ...=... | | TestLoopBranch.java:34:12:34:12 | 2 | TestLoopBranch.java:34:8:34:12 | ... - ... | -| TestLoopBranch.java:37:3:37:3 | stmt | TestLoopBranch.java:38:3:38:3 | stmt | -| TestLoopBranch.java:38:3:38:3 | stmt | TestLoopBranch.java:40:3:40:27 | stmt | -| TestLoopBranch.java:40:3:40:27 | stmt | TestLoopBranch.java:40:24:40:25 | 20 | -| TestLoopBranch.java:40:12:40:12 | j | TestLoopBranch.java:41:3:44:3 | stmt | +| TestLoopBranch.java:37:3:37:3 | ; | TestLoopBranch.java:38:3:38:3 | ; | +| TestLoopBranch.java:38:3:38:3 | ; | TestLoopBranch.java:40:3:40:27 | for (... : ...) | +| TestLoopBranch.java:40:3:40:27 | for (... : ...) | TestLoopBranch.java:40:24:40:25 | 20 | +| TestLoopBranch.java:40:12:40:12 | j | TestLoopBranch.java:41:3:44:3 | { ... } | | TestLoopBranch.java:40:16:40:26 | new int[] | TestLoopBranch.java:40:12:40:12 | j | -| TestLoopBranch.java:40:16:40:26 | new int[] | TestLoopBranch.java:46:3:46:14 | stmt | +| TestLoopBranch.java:40:16:40:26 | new int[] | TestLoopBranch.java:46:3:46:14 | if (...) | | TestLoopBranch.java:40:24:40:25 | 20 | TestLoopBranch.java:40:16:40:26 | new int[] | -| TestLoopBranch.java:41:3:44:3 | stmt | TestLoopBranch.java:42:4:42:37 | stmt | +| TestLoopBranch.java:41:3:44:3 | { ... } | TestLoopBranch.java:42:4:42:37 | ...; | | TestLoopBranch.java:42:4:42:13 | System.out | TestLoopBranch.java:42:23:42:31 | "Zero : " | -| TestLoopBranch.java:42:4:42:36 | println(...) | TestLoopBranch.java:43:4:43:13 | stmt | -| TestLoopBranch.java:42:4:42:37 | stmt | TestLoopBranch.java:42:4:42:13 | System.out | +| TestLoopBranch.java:42:4:42:36 | println(...) | TestLoopBranch.java:43:4:43:13 | ...; | +| TestLoopBranch.java:42:4:42:37 | ...; | TestLoopBranch.java:42:4:42:13 | System.out | | TestLoopBranch.java:42:23:42:31 | "Zero : " | TestLoopBranch.java:42:35:42:35 | j | | TestLoopBranch.java:42:23:42:35 | ... + ... | TestLoopBranch.java:42:4:42:36 | println(...) | | TestLoopBranch.java:42:35:42:35 | j | TestLoopBranch.java:42:23:42:35 | ... + ... | | TestLoopBranch.java:43:4:43:12 | ...=... | TestLoopBranch.java:40:12:40:12 | j | -| TestLoopBranch.java:43:4:43:12 | ...=... | TestLoopBranch.java:46:3:46:14 | stmt | -| TestLoopBranch.java:43:4:43:13 | stmt | TestLoopBranch.java:43:8:43:8 | j | +| TestLoopBranch.java:43:4:43:12 | ...=... | TestLoopBranch.java:46:3:46:14 | if (...) | +| TestLoopBranch.java:43:4:43:13 | ...; | TestLoopBranch.java:43:8:43:8 | j | | TestLoopBranch.java:43:8:43:8 | j | TestLoopBranch.java:43:12:43:12 | x | | TestLoopBranch.java:43:8:43:12 | ... + ... | TestLoopBranch.java:43:4:43:12 | ...=... | | TestLoopBranch.java:43:12:43:12 | x | TestLoopBranch.java:43:8:43:12 | ... + ... | -| TestLoopBranch.java:46:3:46:14 | stmt | TestLoopBranch.java:46:7:46:7 | y | +| TestLoopBranch.java:46:3:46:14 | if (...) | TestLoopBranch.java:46:7:46:7 | y | | TestLoopBranch.java:46:7:46:7 | y | TestLoopBranch.java:46:13:46:13 | 1 | -| TestLoopBranch.java:46:7:46:13 | ... == ... | TestLoopBranch.java:47:3:49:3 | stmt | -| TestLoopBranch.java:46:7:46:13 | ... == ... | TestLoopBranch.java:51:3:51:14 | stmt | +| TestLoopBranch.java:46:7:46:13 | ... == ... | TestLoopBranch.java:47:3:49:3 | { ... } | +| TestLoopBranch.java:46:7:46:13 | ... == ... | TestLoopBranch.java:51:3:51:14 | if (...) | | TestLoopBranch.java:46:12:46:13 | -... | TestLoopBranch.java:46:7:46:13 | ... == ... | | TestLoopBranch.java:46:13:46:13 | 1 | TestLoopBranch.java:46:12:46:13 | -... | -| TestLoopBranch.java:47:3:49:3 | stmt | TestLoopBranch.java:48:4:48:35 | stmt | +| TestLoopBranch.java:47:3:49:3 | { ... } | TestLoopBranch.java:48:4:48:35 | ...; | | TestLoopBranch.java:48:4:48:13 | System.out | TestLoopBranch.java:48:23:48:33 | "i squared" | -| TestLoopBranch.java:48:4:48:34 | println(...) | TestLoopBranch.java:51:3:51:14 | stmt | -| TestLoopBranch.java:48:4:48:35 | stmt | TestLoopBranch.java:48:4:48:13 | System.out | +| TestLoopBranch.java:48:4:48:34 | println(...) | TestLoopBranch.java:51:3:51:14 | if (...) | +| TestLoopBranch.java:48:4:48:35 | ...; | TestLoopBranch.java:48:4:48:13 | System.out | | TestLoopBranch.java:48:23:48:33 | "i squared" | TestLoopBranch.java:48:4:48:34 | println(...) | -| TestLoopBranch.java:51:3:51:14 | stmt | TestLoopBranch.java:51:7:51:7 | x | +| TestLoopBranch.java:51:3:51:14 | if (...) | TestLoopBranch.java:51:7:51:7 | x | | TestLoopBranch.java:51:7:51:7 | x | TestLoopBranch.java:51:12:51:13 | 42 | -| TestLoopBranch.java:51:7:51:13 | ... == ... | TestLoopBranch.java:52:3:55:3 | stmt | -| TestLoopBranch.java:51:7:51:13 | ... == ... | TestLoopBranch.java:56:3:60:3 | stmt | +| TestLoopBranch.java:51:7:51:13 | ... == ... | TestLoopBranch.java:52:3:55:3 | { ... } | +| TestLoopBranch.java:51:7:51:13 | ... == ... | TestLoopBranch.java:56:3:60:3 | { ... } | | TestLoopBranch.java:51:12:51:13 | 42 | TestLoopBranch.java:51:7:51:13 | ... == ... | -| TestLoopBranch.java:52:3:55:3 | stmt | TestLoopBranch.java:53:4:53:29 | stmt | +| TestLoopBranch.java:52:3:55:3 | { ... } | TestLoopBranch.java:53:4:53:29 | ...; | | TestLoopBranch.java:53:4:53:13 | System.out | TestLoopBranch.java:53:23:53:27 | "rat" | -| TestLoopBranch.java:53:4:53:28 | println(...) | TestLoopBranch.java:54:4:54:13 | stmt | -| TestLoopBranch.java:53:4:53:29 | stmt | TestLoopBranch.java:53:4:53:13 | System.out | +| TestLoopBranch.java:53:4:53:28 | println(...) | TestLoopBranch.java:54:4:54:13 | ...; | +| TestLoopBranch.java:53:4:53:29 | ...; | TestLoopBranch.java:53:4:53:13 | System.out | | TestLoopBranch.java:53:23:53:27 | "rat" | TestLoopBranch.java:53:4:53:28 | println(...) | -| TestLoopBranch.java:54:4:54:12 | ...=... | TestLoopBranch.java:62:3:62:12 | stmt | -| TestLoopBranch.java:54:4:54:13 | stmt | TestLoopBranch.java:54:8:54:8 | 6 | +| TestLoopBranch.java:54:4:54:12 | ...=... | TestLoopBranch.java:62:3:62:12 | switch (...) | +| TestLoopBranch.java:54:4:54:13 | ...; | TestLoopBranch.java:54:8:54:8 | 6 | | TestLoopBranch.java:54:8:54:8 | 6 | TestLoopBranch.java:54:12:54:12 | 9 | | TestLoopBranch.java:54:8:54:12 | ... * ... | TestLoopBranch.java:54:4:54:12 | ...=... | | TestLoopBranch.java:54:12:54:12 | 9 | TestLoopBranch.java:54:8:54:12 | ... * ... | -| TestLoopBranch.java:56:3:60:3 | stmt | TestLoopBranch.java:57:4:57:29 | stmt | +| TestLoopBranch.java:56:3:60:3 | { ... } | TestLoopBranch.java:57:4:57:29 | ...; | | TestLoopBranch.java:57:4:57:13 | System.out | TestLoopBranch.java:57:23:57:27 | "arr" | -| TestLoopBranch.java:57:4:57:28 | println(...) | TestLoopBranch.java:58:4:58:13 | stmt | -| TestLoopBranch.java:57:4:57:29 | stmt | TestLoopBranch.java:57:4:57:13 | System.out | +| TestLoopBranch.java:57:4:57:28 | println(...) | TestLoopBranch.java:58:4:58:13 | ...; | +| TestLoopBranch.java:57:4:57:29 | ...; | TestLoopBranch.java:57:4:57:13 | System.out | | TestLoopBranch.java:57:23:57:27 | "arr" | TestLoopBranch.java:57:4:57:28 | println(...) | -| TestLoopBranch.java:58:4:58:12 | ...=... | TestLoopBranch.java:59:4:59:10 | stmt | -| TestLoopBranch.java:58:4:58:13 | stmt | TestLoopBranch.java:58:8:58:8 | y | +| TestLoopBranch.java:58:4:58:12 | ...=... | TestLoopBranch.java:59:4:59:10 | return ... | +| TestLoopBranch.java:58:4:58:13 | ...; | TestLoopBranch.java:58:8:58:8 | y | | TestLoopBranch.java:58:8:58:8 | y | TestLoopBranch.java:58:12:58:12 | x | | TestLoopBranch.java:58:8:58:12 | ... * ... | TestLoopBranch.java:58:4:58:12 | ...=... | | TestLoopBranch.java:58:12:58:12 | x | TestLoopBranch.java:58:8:58:12 | ... * ... | -| TestLoopBranch.java:59:4:59:10 | stmt | TestLoopBranch.java:7:14:7:14 | f | -| TestLoopBranch.java:62:3:62:12 | stmt | TestLoopBranch.java:62:11:62:11 | x | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:64:3:64:9 | stmt | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:67:3:67:9 | stmt | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:71:3:71:9 | stmt | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:72:3:72:9 | stmt | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:76:3:76:9 | stmt | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:77:3:77:9 | stmt | -| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:80:3:80:10 | stmt | -| TestLoopBranch.java:64:3:64:9 | stmt | TestLoopBranch.java:65:4:65:13 | stmt | -| TestLoopBranch.java:65:4:65:12 | ...=... | TestLoopBranch.java:66:4:66:13 | stmt | -| TestLoopBranch.java:65:4:65:13 | stmt | TestLoopBranch.java:65:8:65:8 | x | +| TestLoopBranch.java:59:4:59:10 | return ... | TestLoopBranch.java:7:14:7:14 | f | +| TestLoopBranch.java:62:3:62:12 | switch (...) | TestLoopBranch.java:62:11:62:11 | x | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:64:3:64:9 | case ... | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:67:3:67:9 | case ... | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:71:3:71:9 | case ... | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:72:3:72:9 | case ... | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:76:3:76:9 | case ... | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:77:3:77:9 | case ... | +| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:80:3:80:10 | default | +| TestLoopBranch.java:64:3:64:9 | case ... | TestLoopBranch.java:65:4:65:13 | ...; | +| TestLoopBranch.java:65:4:65:12 | ...=... | TestLoopBranch.java:66:4:66:13 | ...; | +| TestLoopBranch.java:65:4:65:13 | ...; | TestLoopBranch.java:65:8:65:8 | x | | TestLoopBranch.java:65:8:65:8 | x | TestLoopBranch.java:65:12:65:12 | 1 | | TestLoopBranch.java:65:8:65:12 | ... + ... | TestLoopBranch.java:65:4:65:12 | ...=... | | TestLoopBranch.java:65:12:65:12 | 1 | TestLoopBranch.java:65:8:65:12 | ... + ... | -| TestLoopBranch.java:66:4:66:12 | ...=... | TestLoopBranch.java:67:3:67:9 | stmt | -| TestLoopBranch.java:66:4:66:13 | stmt | TestLoopBranch.java:66:8:66:8 | y | +| TestLoopBranch.java:66:4:66:12 | ...=... | TestLoopBranch.java:67:3:67:9 | case ... | +| TestLoopBranch.java:66:4:66:13 | ...; | TestLoopBranch.java:66:8:66:8 | y | | TestLoopBranch.java:66:8:66:8 | y | TestLoopBranch.java:66:12:66:12 | 1 | | TestLoopBranch.java:66:8:66:12 | ... + ... | TestLoopBranch.java:66:4:66:12 | ...=... | | TestLoopBranch.java:66:12:66:12 | 1 | TestLoopBranch.java:66:8:66:12 | ... + ... | -| TestLoopBranch.java:67:3:67:9 | stmt | TestLoopBranch.java:68:4:68:13 | stmt | -| TestLoopBranch.java:68:4:68:12 | ...=... | TestLoopBranch.java:69:4:69:13 | stmt | -| TestLoopBranch.java:68:4:68:13 | stmt | TestLoopBranch.java:68:8:68:8 | x | +| TestLoopBranch.java:67:3:67:9 | case ... | TestLoopBranch.java:68:4:68:13 | ...; | +| TestLoopBranch.java:68:4:68:12 | ...=... | TestLoopBranch.java:69:4:69:13 | ...; | +| TestLoopBranch.java:68:4:68:13 | ...; | TestLoopBranch.java:68:8:68:8 | x | | TestLoopBranch.java:68:8:68:8 | x | TestLoopBranch.java:68:12:68:12 | 2 | | TestLoopBranch.java:68:8:68:12 | ... + ... | TestLoopBranch.java:68:4:68:12 | ...=... | | TestLoopBranch.java:68:12:68:12 | 2 | TestLoopBranch.java:68:8:68:12 | ... + ... | -| TestLoopBranch.java:69:4:69:12 | ...=... | TestLoopBranch.java:70:4:70:9 | stmt | -| TestLoopBranch.java:69:4:69:13 | stmt | TestLoopBranch.java:69:8:69:8 | y | +| TestLoopBranch.java:69:4:69:12 | ...=... | TestLoopBranch.java:70:4:70:9 | break | +| TestLoopBranch.java:69:4:69:13 | ...; | TestLoopBranch.java:69:8:69:8 | y | | TestLoopBranch.java:69:8:69:8 | y | TestLoopBranch.java:69:12:69:12 | 2 | | TestLoopBranch.java:69:8:69:12 | ... + ... | TestLoopBranch.java:69:4:69:12 | ...=... | | TestLoopBranch.java:69:12:69:12 | 2 | TestLoopBranch.java:69:8:69:12 | ... + ... | -| TestLoopBranch.java:70:4:70:9 | stmt | TestLoopBranch.java:86:3:86:11 | stmt | -| TestLoopBranch.java:71:3:71:9 | stmt | TestLoopBranch.java:72:3:72:9 | stmt | -| TestLoopBranch.java:72:3:72:9 | stmt | TestLoopBranch.java:73:4:73:13 | stmt | -| TestLoopBranch.java:73:4:73:12 | ...=... | TestLoopBranch.java:74:4:74:13 | stmt | -| TestLoopBranch.java:73:4:73:13 | stmt | TestLoopBranch.java:73:8:73:8 | x | +| TestLoopBranch.java:70:4:70:9 | break | TestLoopBranch.java:86:3:86:11 | switch (...) | +| TestLoopBranch.java:71:3:71:9 | case ... | TestLoopBranch.java:72:3:72:9 | case ... | +| TestLoopBranch.java:72:3:72:9 | case ... | TestLoopBranch.java:73:4:73:13 | ...; | +| TestLoopBranch.java:73:4:73:12 | ...=... | TestLoopBranch.java:74:4:74:13 | ...; | +| TestLoopBranch.java:73:4:73:13 | ...; | TestLoopBranch.java:73:8:73:8 | x | | TestLoopBranch.java:73:8:73:8 | x | TestLoopBranch.java:73:12:73:12 | 3 | | TestLoopBranch.java:73:8:73:12 | ... + ... | TestLoopBranch.java:73:4:73:12 | ...=... | | TestLoopBranch.java:73:12:73:12 | 3 | TestLoopBranch.java:73:8:73:12 | ... + ... | -| TestLoopBranch.java:74:4:74:12 | ...=... | TestLoopBranch.java:75:4:75:9 | stmt | -| TestLoopBranch.java:74:4:74:13 | stmt | TestLoopBranch.java:74:8:74:8 | y | +| TestLoopBranch.java:74:4:74:12 | ...=... | TestLoopBranch.java:75:4:75:9 | break | +| TestLoopBranch.java:74:4:74:13 | ...; | TestLoopBranch.java:74:8:74:8 | y | | TestLoopBranch.java:74:8:74:8 | y | TestLoopBranch.java:74:12:74:12 | 4 | | TestLoopBranch.java:74:8:74:12 | ... + ... | TestLoopBranch.java:74:4:74:12 | ...=... | | TestLoopBranch.java:74:12:74:12 | 4 | TestLoopBranch.java:74:8:74:12 | ... + ... | -| TestLoopBranch.java:75:4:75:9 | stmt | TestLoopBranch.java:86:3:86:11 | stmt | -| TestLoopBranch.java:76:3:76:9 | stmt | TestLoopBranch.java:77:3:77:9 | stmt | -| TestLoopBranch.java:77:3:77:9 | stmt | TestLoopBranch.java:78:4:78:13 | stmt | -| TestLoopBranch.java:78:4:78:12 | ...=... | TestLoopBranch.java:79:4:79:13 | stmt | -| TestLoopBranch.java:78:4:78:13 | stmt | TestLoopBranch.java:78:8:78:8 | x | +| TestLoopBranch.java:75:4:75:9 | break | TestLoopBranch.java:86:3:86:11 | switch (...) | +| TestLoopBranch.java:76:3:76:9 | case ... | TestLoopBranch.java:77:3:77:9 | case ... | +| TestLoopBranch.java:77:3:77:9 | case ... | TestLoopBranch.java:78:4:78:13 | ...; | +| TestLoopBranch.java:78:4:78:12 | ...=... | TestLoopBranch.java:79:4:79:13 | ...; | +| TestLoopBranch.java:78:4:78:13 | ...; | TestLoopBranch.java:78:8:78:8 | x | | TestLoopBranch.java:78:8:78:8 | x | TestLoopBranch.java:78:12:78:12 | 5 | | TestLoopBranch.java:78:8:78:12 | ... + ... | TestLoopBranch.java:78:4:78:12 | ...=... | | TestLoopBranch.java:78:12:78:12 | 5 | TestLoopBranch.java:78:8:78:12 | ... + ... | -| TestLoopBranch.java:79:4:79:12 | ...=... | TestLoopBranch.java:80:3:80:10 | stmt | -| TestLoopBranch.java:79:4:79:13 | stmt | TestLoopBranch.java:79:8:79:8 | y | +| TestLoopBranch.java:79:4:79:12 | ...=... | TestLoopBranch.java:80:3:80:10 | default | +| TestLoopBranch.java:79:4:79:13 | ...; | TestLoopBranch.java:79:8:79:8 | y | | TestLoopBranch.java:79:8:79:8 | y | TestLoopBranch.java:79:12:79:12 | 6 | | TestLoopBranch.java:79:8:79:12 | ... + ... | TestLoopBranch.java:79:4:79:12 | ...=... | | TestLoopBranch.java:79:12:79:12 | 6 | TestLoopBranch.java:79:8:79:12 | ... + ... | -| TestLoopBranch.java:80:3:80:10 | stmt | TestLoopBranch.java:81:4:81:9 | stmt | -| TestLoopBranch.java:81:4:81:8 | ...=... | TestLoopBranch.java:82:4:82:9 | stmt | -| TestLoopBranch.java:81:4:81:9 | stmt | TestLoopBranch.java:81:8:81:8 | y | +| TestLoopBranch.java:80:3:80:10 | default | TestLoopBranch.java:81:4:81:9 | ...; | +| TestLoopBranch.java:81:4:81:8 | ...=... | TestLoopBranch.java:82:4:82:9 | ...; | +| TestLoopBranch.java:81:4:81:9 | ...; | TestLoopBranch.java:81:8:81:8 | y | | TestLoopBranch.java:81:8:81:8 | y | TestLoopBranch.java:81:4:81:8 | ...=... | -| TestLoopBranch.java:82:4:82:8 | ...=... | TestLoopBranch.java:86:3:86:11 | stmt | -| TestLoopBranch.java:82:4:82:9 | stmt | TestLoopBranch.java:82:8:82:8 | x | +| TestLoopBranch.java:82:4:82:8 | ...=... | TestLoopBranch.java:86:3:86:11 | switch (...) | +| TestLoopBranch.java:82:4:82:9 | ...; | TestLoopBranch.java:82:8:82:8 | x | | TestLoopBranch.java:82:8:82:8 | x | TestLoopBranch.java:82:4:82:8 | ...=... | -| TestLoopBranch.java:86:3:86:11 | stmt | TestLoopBranch.java:86:10:86:10 | x | -| TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:88:3:88:9 | stmt | -| TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:91:3:91:9 | stmt | -| TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:96:3:102:4 | stmt | -| TestLoopBranch.java:88:3:88:9 | stmt | TestLoopBranch.java:89:4:89:9 | stmt | -| TestLoopBranch.java:89:4:89:8 | ...=... | TestLoopBranch.java:90:4:90:9 | stmt | -| TestLoopBranch.java:89:4:89:9 | stmt | TestLoopBranch.java:89:8:89:8 | 1 | +| TestLoopBranch.java:86:3:86:11 | switch (...) | TestLoopBranch.java:86:10:86:10 | x | +| TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:88:3:88:9 | case ... | +| TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:91:3:91:9 | case ... | +| TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:96:3:102:4 | local variable declaration | +| TestLoopBranch.java:88:3:88:9 | case ... | TestLoopBranch.java:89:4:89:9 | ...; | +| TestLoopBranch.java:89:4:89:8 | ...=... | TestLoopBranch.java:90:4:90:9 | break | +| TestLoopBranch.java:89:4:89:9 | ...; | TestLoopBranch.java:89:8:89:8 | 1 | | TestLoopBranch.java:89:8:89:8 | 1 | TestLoopBranch.java:89:4:89:8 | ...=... | -| TestLoopBranch.java:90:4:90:9 | stmt | TestLoopBranch.java:96:3:102:4 | stmt | -| TestLoopBranch.java:91:3:91:9 | stmt | TestLoopBranch.java:92:4:92:9 | stmt | -| TestLoopBranch.java:92:4:92:8 | ...=... | TestLoopBranch.java:93:4:93:9 | stmt | -| TestLoopBranch.java:92:4:92:9 | stmt | TestLoopBranch.java:92:8:92:8 | 2 | +| TestLoopBranch.java:90:4:90:9 | break | TestLoopBranch.java:96:3:102:4 | local variable declaration | +| TestLoopBranch.java:91:3:91:9 | case ... | TestLoopBranch.java:92:4:92:9 | ...; | +| TestLoopBranch.java:92:4:92:8 | ...=... | TestLoopBranch.java:93:4:93:9 | break | +| TestLoopBranch.java:92:4:92:9 | ...; | TestLoopBranch.java:92:8:92:8 | 2 | | TestLoopBranch.java:92:8:92:8 | 2 | TestLoopBranch.java:92:4:92:8 | ...=... | -| TestLoopBranch.java:93:4:93:9 | stmt | TestLoopBranch.java:96:3:102:4 | stmt | -| TestLoopBranch.java:96:3:102:4 | stmt | TestLoopBranch.java:96:26:102:3 | new (...) | -| TestLoopBranch.java:96:22:102:3 | b | TestLoopBranch.java:103:3:103:21 | stmt | +| TestLoopBranch.java:93:4:93:9 | break | TestLoopBranch.java:96:3:102:4 | local variable declaration | +| TestLoopBranch.java:96:3:102:4 | local variable declaration | TestLoopBranch.java:96:26:102:3 | new (...) | +| TestLoopBranch.java:96:22:102:3 | b | TestLoopBranch.java:103:3:103:21 | ...; | | TestLoopBranch.java:96:26:102:3 | new (...) | TestLoopBranch.java:96:22:102:3 | b | -| TestLoopBranch.java:96:30:96:47 | stmt | TestLoopBranch.java:96:30:96:47 | super(...) | | TestLoopBranch.java:96:30:96:47 | super(...) | TestLoopBranch.java:96:30:96:47 | | -| TestLoopBranch.java:99:4:101:4 | stmt | TestLoopBranch.java:100:12:100:12 | 0 | -| TestLoopBranch.java:100:5:100:13 | stmt | TestLoopBranch.java:98:15:98:23 | compareTo | -| TestLoopBranch.java:100:12:100:12 | 0 | TestLoopBranch.java:100:5:100:13 | stmt | +| TestLoopBranch.java:96:30:96:47 | { ... } | TestLoopBranch.java:96:30:96:47 | super(...) | +| TestLoopBranch.java:99:4:101:4 | { ... } | TestLoopBranch.java:100:12:100:12 | 0 | +| TestLoopBranch.java:100:5:100:13 | return ... | TestLoopBranch.java:98:15:98:23 | compareTo | +| TestLoopBranch.java:100:12:100:12 | 0 | TestLoopBranch.java:100:5:100:13 | return ... | | TestLoopBranch.java:103:3:103:3 | b | TestLoopBranch.java:103:15:103:19 | "Foo" | -| TestLoopBranch.java:103:3:103:20 | compareTo(...) | TestLoopBranch.java:105:3:105:12 | stmt | -| TestLoopBranch.java:103:3:103:21 | stmt | TestLoopBranch.java:103:3:103:3 | b | +| TestLoopBranch.java:103:3:103:20 | compareTo(...) | TestLoopBranch.java:105:3:105:12 | ...; | +| TestLoopBranch.java:103:3:103:21 | ...; | TestLoopBranch.java:103:3:103:3 | b | | TestLoopBranch.java:103:15:103:19 | "Foo" | TestLoopBranch.java:103:3:103:20 | compareTo(...) | -| TestLoopBranch.java:105:3:105:11 | ...=... | TestLoopBranch.java:106:3:106:9 | stmt | -| TestLoopBranch.java:105:3:105:12 | stmt | TestLoopBranch.java:105:7:105:7 | x | +| TestLoopBranch.java:105:3:105:11 | ...=... | TestLoopBranch.java:106:3:106:9 | return ... | +| TestLoopBranch.java:105:3:105:12 | ...; | TestLoopBranch.java:105:7:105:7 | x | | TestLoopBranch.java:105:7:105:7 | x | TestLoopBranch.java:105:11:105:11 | y | | TestLoopBranch.java:105:7:105:11 | ... + ... | TestLoopBranch.java:105:3:105:11 | ...=... | | TestLoopBranch.java:105:11:105:11 | y | TestLoopBranch.java:105:7:105:11 | ... + ... | -| TestLoopBranch.java:106:3:106:9 | stmt | TestLoopBranch.java:7:14:7:14 | f | -| TestLoopBranch.java:109:9:109:22 | (...) | TestLoopBranch.java:111:3:111:10 | stmt | -| TestLoopBranch.java:109:9:109:22 | stmt | TestLoopBranch.java:109:9:109:22 | (...) | -| TestLoopBranch.java:109:9:109:22 | super(...) | TestLoopBranch.java:109:9:109:22 | stmt | -| TestLoopBranch.java:110:2:113:2 | stmt | TestLoopBranch.java:109:9:109:22 | super(...) | -| TestLoopBranch.java:111:3:111:9 | ...=... | TestLoopBranch.java:112:3:112:10 | stmt | -| TestLoopBranch.java:111:3:111:10 | stmt | TestLoopBranch.java:111:8:111:9 | 33 | +| TestLoopBranch.java:106:3:106:9 | return ... | TestLoopBranch.java:7:14:7:14 | f | +| TestLoopBranch.java:109:9:109:22 | ...; | TestLoopBranch.java:109:9:109:22 | (...) | +| TestLoopBranch.java:109:9:109:22 | (...) | TestLoopBranch.java:111:3:111:10 | ...; | +| TestLoopBranch.java:109:9:109:22 | super(...) | TestLoopBranch.java:109:9:109:22 | ...; | +| TestLoopBranch.java:110:2:113:2 | { ... } | TestLoopBranch.java:109:9:109:22 | super(...) | +| TestLoopBranch.java:111:3:111:9 | ...=... | TestLoopBranch.java:112:3:112:10 | ...; | +| TestLoopBranch.java:111:3:111:10 | ...; | TestLoopBranch.java:111:8:111:9 | 33 | | TestLoopBranch.java:111:8:111:9 | 33 | TestLoopBranch.java:111:3:111:9 | ...=... | | TestLoopBranch.java:112:3:112:9 | ...=... | TestLoopBranch.java:109:9:109:22 | TestLoopBranch | -| TestLoopBranch.java:112:3:112:10 | stmt | TestLoopBranch.java:112:8:112:9 | 44 | +| TestLoopBranch.java:112:3:112:10 | ...; | TestLoopBranch.java:112:8:112:9 | 44 | | TestLoopBranch.java:112:8:112:9 | 44 | TestLoopBranch.java:112:3:112:9 | ...=... | -| TestLoopBranch.java:115:9:115:22 | (...) | TestLoopBranch.java:117:3:117:9 | stmt | -| TestLoopBranch.java:115:9:115:22 | stmt | TestLoopBranch.java:115:9:115:22 | (...) | -| TestLoopBranch.java:115:9:115:22 | super(...) | TestLoopBranch.java:115:9:115:22 | stmt | -| TestLoopBranch.java:116:2:119:2 | stmt | TestLoopBranch.java:115:9:115:22 | super(...) | -| TestLoopBranch.java:117:3:117:8 | ...=... | TestLoopBranch.java:118:3:118:9 | stmt | -| TestLoopBranch.java:117:3:117:9 | stmt | TestLoopBranch.java:117:8:117:8 | i | +| TestLoopBranch.java:115:9:115:22 | ...; | TestLoopBranch.java:115:9:115:22 | (...) | +| TestLoopBranch.java:115:9:115:22 | (...) | TestLoopBranch.java:117:3:117:9 | ...; | +| TestLoopBranch.java:115:9:115:22 | super(...) | TestLoopBranch.java:115:9:115:22 | ...; | +| TestLoopBranch.java:116:2:119:2 | { ... } | TestLoopBranch.java:115:9:115:22 | super(...) | +| TestLoopBranch.java:117:3:117:8 | ...=... | TestLoopBranch.java:118:3:118:9 | ...; | +| TestLoopBranch.java:117:3:117:9 | ...; | TestLoopBranch.java:117:8:117:8 | i | | TestLoopBranch.java:117:8:117:8 | i | TestLoopBranch.java:117:3:117:8 | ...=... | | TestLoopBranch.java:118:3:118:8 | ...=... | TestLoopBranch.java:115:9:115:22 | TestLoopBranch | -| TestLoopBranch.java:118:3:118:9 | stmt | TestLoopBranch.java:118:8:118:8 | i | +| TestLoopBranch.java:118:3:118:9 | ...; | TestLoopBranch.java:118:8:118:8 | i | | TestLoopBranch.java:118:8:118:8 | i | TestLoopBranch.java:118:3:118:8 | ...=... | diff --git a/java/ql/test/library-tests/successors/TestThrow/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestThrow/FalseSuccessors.expected index 750ad61ecfa..4c6234e019d 100644 --- a/java/ql/test/library-tests/successors/TestThrow/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestThrow/FalseSuccessors.expected @@ -1,12 +1,12 @@ -| TestThrow.java:33:8:33:13 | ... == ... | TestThrow.java:36:11:36:21 | stmt | -| TestThrow.java:36:15:36:20 | ... == ... | TestThrow.java:39:11:39:21 | stmt | -| TestThrow.java:39:15:39:20 | ... == ... | TestThrow.java:43:4:45:4 | stmt | -| TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:62:9:62:19 | stmt | -| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:66:4:68:4 | stmt | -| TestThrow.java:78:8:78:13 | ... == ... | TestThrow.java:81:3:83:3 | stmt | -| TestThrow.java:89:9:89:14 | ... == ... | TestThrow.java:92:12:92:22 | stmt | -| TestThrow.java:92:16:92:21 | ... == ... | TestThrow.java:96:5:98:5 | stmt | -| TestThrow.java:108:9:108:14 | ... == ... | TestThrow.java:111:12:111:22 | stmt | -| TestThrow.java:111:16:111:21 | ... == ... | TestThrow.java:114:12:114:22 | stmt | -| TestThrow.java:114:16:114:21 | ... == ... | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:133:3:133:9 | stmt | +| TestThrow.java:33:8:33:13 | ... == ... | TestThrow.java:36:11:36:21 | if (...) | +| TestThrow.java:36:15:36:20 | ... == ... | TestThrow.java:39:11:39:21 | if (...) | +| TestThrow.java:39:15:39:20 | ... == ... | TestThrow.java:43:4:45:4 | { ... } | +| TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:62:9:62:19 | if (...) | +| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:66:4:68:4 | { ... } | +| TestThrow.java:78:8:78:13 | ... == ... | TestThrow.java:81:3:83:3 | { ... } | +| TestThrow.java:89:9:89:14 | ... == ... | TestThrow.java:92:12:92:22 | if (...) | +| TestThrow.java:92:16:92:21 | ... == ... | TestThrow.java:96:5:98:5 | { ... } | +| TestThrow.java:108:9:108:14 | ... == ... | TestThrow.java:111:12:111:22 | if (...) | +| TestThrow.java:111:16:111:21 | ... == ... | TestThrow.java:114:12:114:22 | if (...) | +| TestThrow.java:114:16:114:21 | ... == ... | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:133:3:133:9 | ...; | diff --git a/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected b/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected index e9d360286d4..aee048401b9 100644 --- a/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected @@ -1,229 +1,229 @@ | TestThrow.java:7:10:7:18 | super(...) | TestThrow.java:7:10:7:18 | TestThrow | -| TestThrow.java:8:2:9:2 | stmt | TestThrow.java:7:10:7:18 | super(...) | -| TestThrow.java:12:2:13:2 | stmt | TestThrow.java:11:15:11:21 | thrower | -| TestThrow.java:16:2:134:2 | stmt | TestThrow.java:17:3:17:12 | stmt | -| TestThrow.java:17:3:17:12 | stmt | TestThrow.java:17:11:17:11 | 0 | -| TestThrow.java:17:7:17:11 | z | TestThrow.java:18:3:27:3 | stmt | +| TestThrow.java:8:2:9:2 | { ... } | TestThrow.java:7:10:7:18 | super(...) | +| TestThrow.java:12:2:13:2 | { ... } | TestThrow.java:11:15:11:21 | thrower | +| TestThrow.java:16:2:134:2 | { ... } | TestThrow.java:17:3:17:12 | local variable declaration | +| TestThrow.java:17:3:17:12 | local variable declaration | TestThrow.java:17:11:17:11 | 0 | +| TestThrow.java:17:7:17:11 | z | TestThrow.java:18:3:27:3 | try ... | | TestThrow.java:17:11:17:11 | 0 | TestThrow.java:17:7:17:11 | z | -| TestThrow.java:18:3:27:3 | stmt | TestThrow.java:19:3:21:3 | stmt | -| TestThrow.java:19:3:21:3 | stmt | TestThrow.java:20:10:20:31 | new RuntimeException(...) | -| TestThrow.java:20:4:20:32 | stmt | TestThrow.java:21:5:21:30 | stmt | -| TestThrow.java:20:10:20:31 | new RuntimeException(...) | TestThrow.java:20:4:20:32 | stmt | -| TestThrow.java:20:10:20:31 | new RuntimeException(...) | TestThrow.java:21:5:21:30 | stmt | -| TestThrow.java:21:5:21:30 | stmt | TestThrow.java:21:29:21:29 | e | -| TestThrow.java:21:29:21:29 | e | TestThrow.java:22:3:24:3 | stmt | -| TestThrow.java:22:3:24:3 | stmt | TestThrow.java:23:4:23:9 | stmt | -| TestThrow.java:23:4:23:8 | ...=... | TestThrow.java:29:3:29:9 | stmt | -| TestThrow.java:23:4:23:9 | stmt | TestThrow.java:23:8:23:8 | 1 | +| TestThrow.java:18:3:27:3 | try ... | TestThrow.java:19:3:21:3 | { ... } | +| TestThrow.java:19:3:21:3 | { ... } | TestThrow.java:20:10:20:31 | new RuntimeException(...) | +| TestThrow.java:20:4:20:32 | throw ... | TestThrow.java:21:5:21:30 | catch (...) | +| TestThrow.java:20:10:20:31 | new RuntimeException(...) | TestThrow.java:20:4:20:32 | throw ... | +| TestThrow.java:20:10:20:31 | new RuntimeException(...) | TestThrow.java:21:5:21:30 | catch (...) | +| TestThrow.java:21:5:21:30 | catch (...) | TestThrow.java:21:29:21:29 | e | +| TestThrow.java:21:29:21:29 | e | TestThrow.java:22:3:24:3 | { ... } | +| TestThrow.java:22:3:24:3 | { ... } | TestThrow.java:23:4:23:9 | ...; | +| TestThrow.java:23:4:23:8 | ...=... | TestThrow.java:29:3:29:9 | ...; | +| TestThrow.java:23:4:23:9 | ...; | TestThrow.java:23:8:23:8 | 1 | | TestThrow.java:23:8:23:8 | 1 | TestThrow.java:23:4:23:8 | ...=... | -| TestThrow.java:24:5:24:23 | stmt | TestThrow.java:24:22:24:22 | e | -| TestThrow.java:24:22:24:22 | e | TestThrow.java:25:3:27:3 | stmt | -| TestThrow.java:25:3:27:3 | stmt | TestThrow.java:26:4:26:9 | stmt | -| TestThrow.java:26:4:26:8 | ...=... | TestThrow.java:29:3:29:9 | stmt | -| TestThrow.java:26:4:26:9 | stmt | TestThrow.java:26:8:26:8 | 2 | +| TestThrow.java:24:5:24:23 | catch (...) | TestThrow.java:24:22:24:22 | e | +| TestThrow.java:24:22:24:22 | e | TestThrow.java:25:3:27:3 | { ... } | +| TestThrow.java:25:3:27:3 | { ... } | TestThrow.java:26:4:26:9 | ...; | +| TestThrow.java:26:4:26:8 | ...=... | TestThrow.java:29:3:29:9 | ...; | +| TestThrow.java:26:4:26:9 | ...; | TestThrow.java:26:8:26:8 | 2 | | TestThrow.java:26:8:26:8 | 2 | TestThrow.java:26:4:26:8 | ...=... | -| TestThrow.java:29:3:29:8 | ...=... | TestThrow.java:31:3:52:3 | stmt | -| TestThrow.java:29:3:29:9 | stmt | TestThrow.java:29:8:29:8 | 1 | +| TestThrow.java:29:3:29:8 | ...=... | TestThrow.java:31:3:52:3 | try ... | +| TestThrow.java:29:3:29:9 | ...; | TestThrow.java:29:8:29:8 | 1 | | TestThrow.java:29:7:29:8 | -... | TestThrow.java:29:3:29:8 | ...=... | | TestThrow.java:29:8:29:8 | 1 | TestThrow.java:29:7:29:8 | -... | -| TestThrow.java:31:3:52:3 | stmt | TestThrow.java:32:3:46:3 | stmt | -| TestThrow.java:32:3:46:3 | stmt | TestThrow.java:33:4:33:14 | stmt | -| TestThrow.java:33:4:33:14 | stmt | TestThrow.java:33:8:33:8 | z | +| TestThrow.java:31:3:52:3 | try ... | TestThrow.java:32:3:46:3 | { ... } | +| TestThrow.java:32:3:46:3 | { ... } | TestThrow.java:33:4:33:14 | if (...) | +| TestThrow.java:33:4:33:14 | if (...) | TestThrow.java:33:8:33:8 | z | | TestThrow.java:33:8:33:8 | z | TestThrow.java:33:13:33:13 | 1 | -| TestThrow.java:33:8:33:13 | ... == ... | TestThrow.java:34:4:36:4 | stmt | -| TestThrow.java:33:8:33:13 | ... == ... | TestThrow.java:36:11:36:21 | stmt | +| TestThrow.java:33:8:33:13 | ... == ... | TestThrow.java:34:4:36:4 | { ... } | +| TestThrow.java:33:8:33:13 | ... == ... | TestThrow.java:36:11:36:21 | if (...) | | TestThrow.java:33:13:33:13 | 1 | TestThrow.java:33:8:33:13 | ... == ... | -| TestThrow.java:34:4:36:4 | stmt | TestThrow.java:35:11:35:32 | new RuntimeException(...) | -| TestThrow.java:35:5:35:33 | stmt | TestThrow.java:46:5:46:30 | stmt | -| TestThrow.java:35:11:35:32 | new RuntimeException(...) | TestThrow.java:35:5:35:33 | stmt | -| TestThrow.java:35:11:35:32 | new RuntimeException(...) | TestThrow.java:46:5:46:30 | stmt | -| TestThrow.java:35:11:35:32 | new RuntimeException(...) | TestThrow.java:50:3:52:3 | stmt | -| TestThrow.java:36:11:36:21 | stmt | TestThrow.java:36:15:36:15 | z | +| TestThrow.java:34:4:36:4 | { ... } | TestThrow.java:35:11:35:32 | new RuntimeException(...) | +| TestThrow.java:35:5:35:33 | throw ... | TestThrow.java:46:5:46:30 | catch (...) | +| TestThrow.java:35:11:35:32 | new RuntimeException(...) | TestThrow.java:35:5:35:33 | throw ... | +| TestThrow.java:35:11:35:32 | new RuntimeException(...) | TestThrow.java:46:5:46:30 | catch (...) | +| TestThrow.java:35:11:35:32 | new RuntimeException(...) | TestThrow.java:50:3:52:3 | { ... } | +| TestThrow.java:36:11:36:21 | if (...) | TestThrow.java:36:15:36:15 | z | | TestThrow.java:36:15:36:15 | z | TestThrow.java:36:20:36:20 | 2 | -| TestThrow.java:36:15:36:20 | ... == ... | TestThrow.java:37:4:39:4 | stmt | -| TestThrow.java:36:15:36:20 | ... == ... | TestThrow.java:39:11:39:21 | stmt | +| TestThrow.java:36:15:36:20 | ... == ... | TestThrow.java:37:4:39:4 | { ... } | +| TestThrow.java:36:15:36:20 | ... == ... | TestThrow.java:39:11:39:21 | if (...) | | TestThrow.java:36:20:36:20 | 2 | TestThrow.java:36:15:36:20 | ... == ... | -| TestThrow.java:37:4:39:4 | stmt | TestThrow.java:38:11:38:25 | new Exception(...) | -| TestThrow.java:38:5:38:26 | stmt | TestThrow.java:46:5:46:30 | stmt | -| TestThrow.java:38:5:38:26 | stmt | TestThrow.java:50:3:52:3 | stmt | -| TestThrow.java:38:11:38:25 | new Exception(...) | TestThrow.java:38:5:38:26 | stmt | -| TestThrow.java:38:11:38:25 | new Exception(...) | TestThrow.java:46:5:46:30 | stmt | -| TestThrow.java:38:11:38:25 | new Exception(...) | TestThrow.java:50:3:52:3 | stmt | -| TestThrow.java:39:11:39:21 | stmt | TestThrow.java:39:15:39:15 | z | +| TestThrow.java:37:4:39:4 | { ... } | TestThrow.java:38:11:38:25 | new Exception(...) | +| TestThrow.java:38:5:38:26 | throw ... | TestThrow.java:46:5:46:30 | catch (...) | +| TestThrow.java:38:5:38:26 | throw ... | TestThrow.java:50:3:52:3 | { ... } | +| TestThrow.java:38:11:38:25 | new Exception(...) | TestThrow.java:38:5:38:26 | throw ... | +| TestThrow.java:38:11:38:25 | new Exception(...) | TestThrow.java:46:5:46:30 | catch (...) | +| TestThrow.java:38:11:38:25 | new Exception(...) | TestThrow.java:50:3:52:3 | { ... } | +| TestThrow.java:39:11:39:21 | if (...) | TestThrow.java:39:15:39:15 | z | | TestThrow.java:39:15:39:15 | z | TestThrow.java:39:20:39:20 | 3 | -| TestThrow.java:39:15:39:20 | ... == ... | TestThrow.java:40:4:42:4 | stmt | -| TestThrow.java:39:15:39:20 | ... == ... | TestThrow.java:43:4:45:4 | stmt | +| TestThrow.java:39:15:39:20 | ... == ... | TestThrow.java:40:4:42:4 | { ... } | +| TestThrow.java:39:15:39:20 | ... == ... | TestThrow.java:43:4:45:4 | { ... } | | TestThrow.java:39:20:39:20 | 3 | TestThrow.java:39:15:39:20 | ... == ... | -| TestThrow.java:40:4:42:4 | stmt | TestThrow.java:41:5:41:20 | stmt | -| TestThrow.java:41:5:41:19 | new TestThrow(...) | TestThrow.java:46:5:46:30 | stmt | -| TestThrow.java:41:5:41:19 | new TestThrow(...) | TestThrow.java:50:3:52:3 | stmt | -| TestThrow.java:41:5:41:20 | stmt | TestThrow.java:41:5:41:19 | new TestThrow(...) | -| TestThrow.java:43:4:45:4 | stmt | TestThrow.java:44:5:44:14 | stmt | -| TestThrow.java:44:5:44:13 | thrower(...) | TestThrow.java:46:5:46:30 | stmt | -| TestThrow.java:44:5:44:13 | thrower(...) | TestThrow.java:50:3:52:3 | stmt | -| TestThrow.java:44:5:44:14 | stmt | TestThrow.java:44:5:44:13 | thrower(...) | -| TestThrow.java:46:5:46:30 | stmt | TestThrow.java:46:29:46:29 | e | -| TestThrow.java:46:29:46:29 | e | TestThrow.java:47:3:49:3 | stmt | -| TestThrow.java:47:3:49:3 | stmt | TestThrow.java:48:4:48:9 | stmt | -| TestThrow.java:48:4:48:8 | ...=... | TestThrow.java:50:3:52:3 | stmt | -| TestThrow.java:48:4:48:9 | stmt | TestThrow.java:48:8:48:8 | 1 | +| TestThrow.java:40:4:42:4 | { ... } | TestThrow.java:41:5:41:20 | ...; | +| TestThrow.java:41:5:41:19 | new TestThrow(...) | TestThrow.java:46:5:46:30 | catch (...) | +| TestThrow.java:41:5:41:19 | new TestThrow(...) | TestThrow.java:50:3:52:3 | { ... } | +| TestThrow.java:41:5:41:20 | ...; | TestThrow.java:41:5:41:19 | new TestThrow(...) | +| TestThrow.java:43:4:45:4 | { ... } | TestThrow.java:44:5:44:14 | ...; | +| TestThrow.java:44:5:44:13 | thrower(...) | TestThrow.java:46:5:46:30 | catch (...) | +| TestThrow.java:44:5:44:13 | thrower(...) | TestThrow.java:50:3:52:3 | { ... } | +| TestThrow.java:44:5:44:14 | ...; | TestThrow.java:44:5:44:13 | thrower(...) | +| TestThrow.java:46:5:46:30 | catch (...) | TestThrow.java:46:29:46:29 | e | +| TestThrow.java:46:29:46:29 | e | TestThrow.java:47:3:49:3 | { ... } | +| TestThrow.java:47:3:49:3 | { ... } | TestThrow.java:48:4:48:9 | ...; | +| TestThrow.java:48:4:48:8 | ...=... | TestThrow.java:50:3:52:3 | { ... } | +| TestThrow.java:48:4:48:9 | ...; | TestThrow.java:48:8:48:8 | 1 | | TestThrow.java:48:8:48:8 | 1 | TestThrow.java:48:4:48:8 | ...=... | -| TestThrow.java:50:3:52:3 | stmt | TestThrow.java:51:4:51:9 | stmt | +| TestThrow.java:50:3:52:3 | { ... } | TestThrow.java:51:4:51:9 | ...; | | TestThrow.java:51:4:51:8 | ...=... | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:51:4:51:8 | ...=... | TestThrow.java:54:3:54:9 | stmt | -| TestThrow.java:51:4:51:9 | stmt | TestThrow.java:51:8:51:8 | 2 | +| TestThrow.java:51:4:51:8 | ...=... | TestThrow.java:54:3:54:9 | ...; | +| TestThrow.java:51:4:51:9 | ...; | TestThrow.java:51:8:51:8 | 2 | | TestThrow.java:51:8:51:8 | 2 | TestThrow.java:51:4:51:8 | ...=... | -| TestThrow.java:54:3:54:8 | ...=... | TestThrow.java:56:3:72:3 | stmt | -| TestThrow.java:54:3:54:9 | stmt | TestThrow.java:54:8:54:8 | 1 | +| TestThrow.java:54:3:54:8 | ...=... | TestThrow.java:56:3:72:3 | try ... | +| TestThrow.java:54:3:54:9 | ...; | TestThrow.java:54:8:54:8 | 1 | | TestThrow.java:54:7:54:8 | -... | TestThrow.java:54:3:54:8 | ...=... | | TestThrow.java:54:8:54:8 | 1 | TestThrow.java:54:7:54:8 | -... | -| TestThrow.java:56:3:72:3 | stmt | TestThrow.java:57:3:69:3 | stmt | -| TestThrow.java:57:3:69:3 | stmt | TestThrow.java:58:4:58:14 | stmt | -| TestThrow.java:58:4:58:14 | stmt | TestThrow.java:58:8:58:8 | z | +| TestThrow.java:56:3:72:3 | try ... | TestThrow.java:57:3:69:3 | { ... } | +| TestThrow.java:57:3:69:3 | { ... } | TestThrow.java:58:4:58:14 | if (...) | +| TestThrow.java:58:4:58:14 | if (...) | TestThrow.java:58:8:58:8 | z | | TestThrow.java:58:8:58:8 | z | TestThrow.java:58:13:58:13 | 1 | -| TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:59:4:61:4 | stmt | -| TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:62:9:62:19 | stmt | +| TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:59:4:61:4 | { ... } | +| TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:62:9:62:19 | if (...) | | TestThrow.java:58:13:58:13 | 1 | TestThrow.java:58:8:58:13 | ... == ... | -| TestThrow.java:59:4:61:4 | stmt | TestThrow.java:60:11:60:25 | new Exception(...) | -| TestThrow.java:60:5:60:26 | stmt | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:60:5:60:26 | stmt | TestThrow.java:69:5:69:30 | stmt | -| TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:60:5:60:26 | stmt | -| TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:69:5:69:30 | stmt | -| TestThrow.java:62:9:62:19 | stmt | TestThrow.java:62:13:62:13 | z | +| TestThrow.java:59:4:61:4 | { ... } | TestThrow.java:60:11:60:25 | new Exception(...) | +| TestThrow.java:60:5:60:26 | throw ... | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:60:5:60:26 | throw ... | TestThrow.java:69:5:69:30 | catch (...) | +| TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:60:5:60:26 | throw ... | +| TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:69:5:69:30 | catch (...) | +| TestThrow.java:62:9:62:19 | if (...) | TestThrow.java:62:13:62:13 | z | | TestThrow.java:62:13:62:13 | z | TestThrow.java:62:18:62:18 | 2 | -| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:63:4:65:4 | stmt | -| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:66:4:68:4 | stmt | +| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:63:4:65:4 | { ... } | +| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:66:4:68:4 | { ... } | | TestThrow.java:62:18:62:18 | 2 | TestThrow.java:62:13:62:18 | ... == ... | -| TestThrow.java:63:4:65:4 | stmt | TestThrow.java:64:5:64:20 | stmt | +| TestThrow.java:63:4:65:4 | { ... } | TestThrow.java:64:5:64:20 | ...; | | TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:69:5:69:30 | stmt | -| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:74:3:74:9 | stmt | -| TestThrow.java:64:5:64:20 | stmt | TestThrow.java:64:5:64:19 | new TestThrow(...) | -| TestThrow.java:66:4:68:4 | stmt | TestThrow.java:67:5:67:14 | stmt | -| TestThrow.java:67:5:67:13 | thrower(...) | TestThrow.java:69:5:69:30 | stmt | -| TestThrow.java:67:5:67:13 | thrower(...) | TestThrow.java:74:3:74:9 | stmt | -| TestThrow.java:67:5:67:14 | stmt | TestThrow.java:67:5:67:13 | thrower(...) | -| TestThrow.java:69:5:69:30 | stmt | TestThrow.java:69:29:69:29 | e | -| TestThrow.java:69:29:69:29 | e | TestThrow.java:70:3:72:3 | stmt | -| TestThrow.java:70:3:72:3 | stmt | TestThrow.java:71:4:71:9 | stmt | -| TestThrow.java:71:4:71:8 | ...=... | TestThrow.java:74:3:74:9 | stmt | -| TestThrow.java:71:4:71:9 | stmt | TestThrow.java:71:8:71:8 | 1 | +| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:69:5:69:30 | catch (...) | +| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:74:3:74:9 | ...; | +| TestThrow.java:64:5:64:20 | ...; | TestThrow.java:64:5:64:19 | new TestThrow(...) | +| TestThrow.java:66:4:68:4 | { ... } | TestThrow.java:67:5:67:14 | ...; | +| TestThrow.java:67:5:67:13 | thrower(...) | TestThrow.java:69:5:69:30 | catch (...) | +| TestThrow.java:67:5:67:13 | thrower(...) | TestThrow.java:74:3:74:9 | ...; | +| TestThrow.java:67:5:67:14 | ...; | TestThrow.java:67:5:67:13 | thrower(...) | +| TestThrow.java:69:5:69:30 | catch (...) | TestThrow.java:69:29:69:29 | e | +| TestThrow.java:69:29:69:29 | e | TestThrow.java:70:3:72:3 | { ... } | +| TestThrow.java:70:3:72:3 | { ... } | TestThrow.java:71:4:71:9 | ...; | +| TestThrow.java:71:4:71:8 | ...=... | TestThrow.java:74:3:74:9 | ...; | +| TestThrow.java:71:4:71:9 | ...; | TestThrow.java:71:8:71:8 | 1 | | TestThrow.java:71:8:71:8 | 1 | TestThrow.java:71:4:71:8 | ...=... | -| TestThrow.java:74:3:74:8 | ...=... | TestThrow.java:76:3:83:3 | stmt | -| TestThrow.java:74:3:74:9 | stmt | TestThrow.java:74:8:74:8 | 1 | +| TestThrow.java:74:3:74:8 | ...=... | TestThrow.java:76:3:83:3 | try ... | +| TestThrow.java:74:3:74:9 | ...; | TestThrow.java:74:8:74:8 | 1 | | TestThrow.java:74:7:74:8 | -... | TestThrow.java:74:3:74:8 | ...=... | | TestThrow.java:74:8:74:8 | 1 | TestThrow.java:74:7:74:8 | -... | -| TestThrow.java:76:3:83:3 | stmt | TestThrow.java:77:3:80:3 | stmt | -| TestThrow.java:77:3:80:3 | stmt | TestThrow.java:78:4:78:14 | stmt | -| TestThrow.java:78:4:78:14 | stmt | TestThrow.java:78:8:78:8 | z | +| TestThrow.java:76:3:83:3 | try ... | TestThrow.java:77:3:80:3 | { ... } | +| TestThrow.java:77:3:80:3 | { ... } | TestThrow.java:78:4:78:14 | if (...) | +| TestThrow.java:78:4:78:14 | if (...) | TestThrow.java:78:8:78:8 | z | | TestThrow.java:78:8:78:8 | z | TestThrow.java:78:13:78:13 | 1 | | TestThrow.java:78:8:78:13 | ... == ... | TestThrow.java:79:11:79:25 | new Exception(...) | -| TestThrow.java:78:8:78:13 | ... == ... | TestThrow.java:81:3:83:3 | stmt | +| TestThrow.java:78:8:78:13 | ... == ... | TestThrow.java:81:3:83:3 | { ... } | | TestThrow.java:78:13:78:13 | 1 | TestThrow.java:78:8:78:13 | ... == ... | -| TestThrow.java:79:5:79:26 | stmt | TestThrow.java:81:3:83:3 | stmt | -| TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:79:5:79:26 | stmt | -| TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:81:3:83:3 | stmt | -| TestThrow.java:81:3:83:3 | stmt | TestThrow.java:82:4:82:9 | stmt | +| TestThrow.java:79:5:79:26 | throw ... | TestThrow.java:81:3:83:3 | { ... } | +| TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:79:5:79:26 | throw ... | +| TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:81:3:83:3 | { ... } | +| TestThrow.java:81:3:83:3 | { ... } | TestThrow.java:82:4:82:9 | ...; | | TestThrow.java:82:4:82:8 | ...=... | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:82:4:82:8 | ...=... | TestThrow.java:85:3:126:3 | stmt | -| TestThrow.java:82:4:82:9 | stmt | TestThrow.java:82:8:82:8 | 1 | +| TestThrow.java:82:4:82:8 | ...=... | TestThrow.java:85:3:126:3 | try ... | +| TestThrow.java:82:4:82:9 | ...; | TestThrow.java:82:8:82:8 | 1 | | TestThrow.java:82:8:82:8 | 1 | TestThrow.java:82:4:82:8 | ...=... | -| TestThrow.java:85:3:126:3 | stmt | TestThrow.java:86:3:119:3 | stmt | -| TestThrow.java:86:3:119:3 | stmt | TestThrow.java:87:4:102:4 | stmt | -| TestThrow.java:87:4:102:4 | stmt | TestThrow.java:88:4:99:4 | stmt | -| TestThrow.java:88:4:99:4 | stmt | TestThrow.java:89:5:89:15 | stmt | -| TestThrow.java:89:5:89:15 | stmt | TestThrow.java:89:9:89:9 | z | +| TestThrow.java:85:3:126:3 | try ... | TestThrow.java:86:3:119:3 | { ... } | +| TestThrow.java:86:3:119:3 | { ... } | TestThrow.java:87:4:102:4 | try ... | +| TestThrow.java:87:4:102:4 | try ... | TestThrow.java:88:4:99:4 | { ... } | +| TestThrow.java:88:4:99:4 | { ... } | TestThrow.java:89:5:89:15 | if (...) | +| TestThrow.java:89:5:89:15 | if (...) | TestThrow.java:89:9:89:9 | z | | TestThrow.java:89:9:89:9 | z | TestThrow.java:89:14:89:14 | 1 | -| TestThrow.java:89:9:89:14 | ... == ... | TestThrow.java:90:5:92:5 | stmt | -| TestThrow.java:89:9:89:14 | ... == ... | TestThrow.java:92:12:92:22 | stmt | +| TestThrow.java:89:9:89:14 | ... == ... | TestThrow.java:90:5:92:5 | { ... } | +| TestThrow.java:89:9:89:14 | ... == ... | TestThrow.java:92:12:92:22 | if (...) | | TestThrow.java:89:14:89:14 | 1 | TestThrow.java:89:9:89:14 | ... == ... | -| TestThrow.java:90:5:92:5 | stmt | TestThrow.java:91:12:91:26 | new Exception(...) | -| TestThrow.java:91:6:91:27 | stmt | TestThrow.java:99:6:99:31 | stmt | -| TestThrow.java:91:6:91:27 | stmt | TestThrow.java:119:5:119:25 | stmt | -| TestThrow.java:91:6:91:27 | stmt | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:91:12:91:26 | new Exception(...) | TestThrow.java:91:6:91:27 | stmt | -| TestThrow.java:91:12:91:26 | new Exception(...) | TestThrow.java:99:6:99:31 | stmt | -| TestThrow.java:91:12:91:26 | new Exception(...) | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:92:12:92:22 | stmt | TestThrow.java:92:16:92:16 | z | +| TestThrow.java:90:5:92:5 | { ... } | TestThrow.java:91:12:91:26 | new Exception(...) | +| TestThrow.java:91:6:91:27 | throw ... | TestThrow.java:99:6:99:31 | catch (...) | +| TestThrow.java:91:6:91:27 | throw ... | TestThrow.java:119:5:119:25 | catch (...) | +| TestThrow.java:91:6:91:27 | throw ... | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:91:12:91:26 | new Exception(...) | TestThrow.java:91:6:91:27 | throw ... | +| TestThrow.java:91:12:91:26 | new Exception(...) | TestThrow.java:99:6:99:31 | catch (...) | +| TestThrow.java:91:12:91:26 | new Exception(...) | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:92:12:92:22 | if (...) | TestThrow.java:92:16:92:16 | z | | TestThrow.java:92:16:92:16 | z | TestThrow.java:92:21:92:21 | 2 | -| TestThrow.java:92:16:92:21 | ... == ... | TestThrow.java:93:5:95:5 | stmt | -| TestThrow.java:92:16:92:21 | ... == ... | TestThrow.java:96:5:98:5 | stmt | +| TestThrow.java:92:16:92:21 | ... == ... | TestThrow.java:93:5:95:5 | { ... } | +| TestThrow.java:92:16:92:21 | ... == ... | TestThrow.java:96:5:98:5 | { ... } | | TestThrow.java:92:21:92:21 | 2 | TestThrow.java:92:16:92:21 | ... == ... | -| TestThrow.java:93:5:95:5 | stmt | TestThrow.java:94:12:94:33 | new RuntimeException(...) | -| TestThrow.java:94:6:94:34 | stmt | TestThrow.java:99:6:99:31 | stmt | -| TestThrow.java:94:12:94:33 | new RuntimeException(...) | TestThrow.java:94:6:94:34 | stmt | -| TestThrow.java:94:12:94:33 | new RuntimeException(...) | TestThrow.java:99:6:99:31 | stmt | -| TestThrow.java:94:12:94:33 | new RuntimeException(...) | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:96:5:98:5 | stmt | TestThrow.java:97:28:97:36 | "Foo bar" | -| TestThrow.java:97:6:97:44 | stmt | TestThrow.java:119:5:119:25 | stmt | -| TestThrow.java:97:12:97:43 | new IOException(...) | TestThrow.java:97:6:97:44 | stmt | -| TestThrow.java:97:12:97:43 | new IOException(...) | TestThrow.java:99:6:99:31 | stmt | -| TestThrow.java:97:12:97:43 | new IOException(...) | TestThrow.java:124:3:126:3 | stmt | +| TestThrow.java:93:5:95:5 | { ... } | TestThrow.java:94:12:94:33 | new RuntimeException(...) | +| TestThrow.java:94:6:94:34 | throw ... | TestThrow.java:99:6:99:31 | catch (...) | +| TestThrow.java:94:12:94:33 | new RuntimeException(...) | TestThrow.java:94:6:94:34 | throw ... | +| TestThrow.java:94:12:94:33 | new RuntimeException(...) | TestThrow.java:99:6:99:31 | catch (...) | +| TestThrow.java:94:12:94:33 | new RuntimeException(...) | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:96:5:98:5 | { ... } | TestThrow.java:97:28:97:36 | "Foo bar" | +| TestThrow.java:97:6:97:44 | throw ... | TestThrow.java:119:5:119:25 | catch (...) | +| TestThrow.java:97:12:97:43 | new IOException(...) | TestThrow.java:97:6:97:44 | throw ... | +| TestThrow.java:97:12:97:43 | new IOException(...) | TestThrow.java:99:6:99:31 | catch (...) | +| TestThrow.java:97:12:97:43 | new IOException(...) | TestThrow.java:124:3:126:3 | { ... } | | TestThrow.java:97:28:97:36 | "Foo bar" | TestThrow.java:97:39:97:42 | null | | TestThrow.java:97:39:97:42 | null | TestThrow.java:97:12:97:43 | new IOException(...) | -| TestThrow.java:99:6:99:31 | stmt | TestThrow.java:99:30:99:30 | e | -| TestThrow.java:99:30:99:30 | e | TestThrow.java:100:4:102:4 | stmt | -| TestThrow.java:100:4:102:4 | stmt | TestThrow.java:101:5:101:10 | stmt | -| TestThrow.java:101:5:101:9 | ...=... | TestThrow.java:103:4:118:4 | stmt | -| TestThrow.java:101:5:101:10 | stmt | TestThrow.java:101:9:101:9 | 1 | +| TestThrow.java:99:6:99:31 | catch (...) | TestThrow.java:99:30:99:30 | e | +| TestThrow.java:99:30:99:30 | e | TestThrow.java:100:4:102:4 | { ... } | +| TestThrow.java:100:4:102:4 | { ... } | TestThrow.java:101:5:101:10 | ...; | +| TestThrow.java:101:5:101:9 | ...=... | TestThrow.java:103:4:118:4 | try ... | +| TestThrow.java:101:5:101:10 | ...; | TestThrow.java:101:9:101:9 | 1 | | TestThrow.java:101:9:101:9 | 1 | TestThrow.java:101:5:101:9 | ...=... | -| TestThrow.java:103:4:118:4 | stmt | TestThrow.java:104:4:106:4 | stmt | -| TestThrow.java:104:4:106:4 | stmt | TestThrow.java:105:5:105:11 | stmt | -| TestThrow.java:105:5:105:10 | ...=... | TestThrow.java:107:4:118:4 | stmt | -| TestThrow.java:105:5:105:11 | stmt | TestThrow.java:105:10:105:10 | 2 | +| TestThrow.java:103:4:118:4 | try ... | TestThrow.java:104:4:106:4 | { ... } | +| TestThrow.java:104:4:106:4 | { ... } | TestThrow.java:105:5:105:11 | ...; | +| TestThrow.java:105:5:105:10 | ...=... | TestThrow.java:107:4:118:4 | { ... } | +| TestThrow.java:105:5:105:11 | ...; | TestThrow.java:105:10:105:10 | 2 | | TestThrow.java:105:9:105:10 | -... | TestThrow.java:105:5:105:10 | ...=... | | TestThrow.java:105:10:105:10 | 2 | TestThrow.java:105:9:105:10 | -... | -| TestThrow.java:107:4:118:4 | stmt | TestThrow.java:108:5:108:15 | stmt | -| TestThrow.java:108:5:108:15 | stmt | TestThrow.java:108:9:108:9 | z | +| TestThrow.java:107:4:118:4 | { ... } | TestThrow.java:108:5:108:15 | if (...) | +| TestThrow.java:108:5:108:15 | if (...) | TestThrow.java:108:9:108:9 | z | | TestThrow.java:108:9:108:9 | z | TestThrow.java:108:14:108:14 | 1 | -| TestThrow.java:108:9:108:14 | ... == ... | TestThrow.java:109:5:111:5 | stmt | -| TestThrow.java:108:9:108:14 | ... == ... | TestThrow.java:111:12:111:22 | stmt | +| TestThrow.java:108:9:108:14 | ... == ... | TestThrow.java:109:5:111:5 | { ... } | +| TestThrow.java:108:9:108:14 | ... == ... | TestThrow.java:111:12:111:22 | if (...) | | TestThrow.java:108:14:108:14 | 1 | TestThrow.java:108:9:108:14 | ... == ... | -| TestThrow.java:109:5:111:5 | stmt | TestThrow.java:110:12:110:26 | new Exception(...) | -| TestThrow.java:110:6:110:27 | stmt | TestThrow.java:119:5:119:25 | stmt | -| TestThrow.java:110:6:110:27 | stmt | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:110:12:110:26 | new Exception(...) | TestThrow.java:110:6:110:27 | stmt | -| TestThrow.java:110:12:110:26 | new Exception(...) | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:111:12:111:22 | stmt | TestThrow.java:111:16:111:16 | z | +| TestThrow.java:109:5:111:5 | { ... } | TestThrow.java:110:12:110:26 | new Exception(...) | +| TestThrow.java:110:6:110:27 | throw ... | TestThrow.java:119:5:119:25 | catch (...) | +| TestThrow.java:110:6:110:27 | throw ... | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:110:12:110:26 | new Exception(...) | TestThrow.java:110:6:110:27 | throw ... | +| TestThrow.java:110:12:110:26 | new Exception(...) | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:111:12:111:22 | if (...) | TestThrow.java:111:16:111:16 | z | | TestThrow.java:111:16:111:16 | z | TestThrow.java:111:21:111:21 | 2 | -| TestThrow.java:111:16:111:21 | ... == ... | TestThrow.java:112:5:114:5 | stmt | -| TestThrow.java:111:16:111:21 | ... == ... | TestThrow.java:114:12:114:22 | stmt | +| TestThrow.java:111:16:111:21 | ... == ... | TestThrow.java:112:5:114:5 | { ... } | +| TestThrow.java:111:16:111:21 | ... == ... | TestThrow.java:114:12:114:22 | if (...) | | TestThrow.java:111:21:111:21 | 2 | TestThrow.java:111:16:111:21 | ... == ... | -| TestThrow.java:112:5:114:5 | stmt | TestThrow.java:113:12:113:33 | new RuntimeException(...) | -| TestThrow.java:113:6:113:34 | stmt | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:113:12:113:33 | new RuntimeException(...) | TestThrow.java:113:6:113:34 | stmt | -| TestThrow.java:113:12:113:33 | new RuntimeException(...) | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:114:12:114:22 | stmt | TestThrow.java:114:16:114:16 | z | +| TestThrow.java:112:5:114:5 | { ... } | TestThrow.java:113:12:113:33 | new RuntimeException(...) | +| TestThrow.java:113:6:113:34 | throw ... | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:113:12:113:33 | new RuntimeException(...) | TestThrow.java:113:6:113:34 | throw ... | +| TestThrow.java:113:12:113:33 | new RuntimeException(...) | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:114:12:114:22 | if (...) | TestThrow.java:114:16:114:16 | z | | TestThrow.java:114:16:114:16 | z | TestThrow.java:114:21:114:21 | 3 | -| TestThrow.java:114:16:114:21 | ... == ... | TestThrow.java:115:5:117:5 | stmt | -| TestThrow.java:114:16:114:21 | ... == ... | TestThrow.java:124:3:126:3 | stmt | +| TestThrow.java:114:16:114:21 | ... == ... | TestThrow.java:115:5:117:5 | { ... } | +| TestThrow.java:114:16:114:21 | ... == ... | TestThrow.java:124:3:126:3 | { ... } | | TestThrow.java:114:21:114:21 | 3 | TestThrow.java:114:16:114:21 | ... == ... | -| TestThrow.java:115:5:117:5 | stmt | TestThrow.java:116:28:116:36 | "Foo bar" | -| TestThrow.java:116:6:116:44 | stmt | TestThrow.java:119:5:119:25 | stmt | -| TestThrow.java:116:12:116:43 | new IOException(...) | TestThrow.java:116:6:116:44 | stmt | -| TestThrow.java:116:12:116:43 | new IOException(...) | TestThrow.java:124:3:126:3 | stmt | +| TestThrow.java:115:5:117:5 | { ... } | TestThrow.java:116:28:116:36 | "Foo bar" | +| TestThrow.java:116:6:116:44 | throw ... | TestThrow.java:119:5:119:25 | catch (...) | +| TestThrow.java:116:12:116:43 | new IOException(...) | TestThrow.java:116:6:116:44 | throw ... | +| TestThrow.java:116:12:116:43 | new IOException(...) | TestThrow.java:124:3:126:3 | { ... } | | TestThrow.java:116:28:116:36 | "Foo bar" | TestThrow.java:116:39:116:42 | null | | TestThrow.java:116:39:116:42 | null | TestThrow.java:116:12:116:43 | new IOException(...) | -| TestThrow.java:119:5:119:25 | stmt | TestThrow.java:119:24:119:24 | e | -| TestThrow.java:119:24:119:24 | e | TestThrow.java:120:3:122:3 | stmt | -| TestThrow.java:120:3:122:3 | stmt | TestThrow.java:121:4:121:9 | stmt | -| TestThrow.java:121:4:121:8 | ...=... | TestThrow.java:124:3:126:3 | stmt | -| TestThrow.java:121:4:121:9 | stmt | TestThrow.java:121:8:121:8 | 2 | +| TestThrow.java:119:5:119:25 | catch (...) | TestThrow.java:119:24:119:24 | e | +| TestThrow.java:119:24:119:24 | e | TestThrow.java:120:3:122:3 | { ... } | +| TestThrow.java:120:3:122:3 | { ... } | TestThrow.java:121:4:121:9 | ...; | +| TestThrow.java:121:4:121:8 | ...=... | TestThrow.java:124:3:126:3 | { ... } | +| TestThrow.java:121:4:121:9 | ...; | TestThrow.java:121:8:121:8 | 2 | | TestThrow.java:121:8:121:8 | 2 | TestThrow.java:121:4:121:8 | ...=... | -| TestThrow.java:124:3:126:3 | stmt | TestThrow.java:125:4:125:9 | stmt | +| TestThrow.java:124:3:126:3 | { ... } | TestThrow.java:125:4:125:9 | ...; | | TestThrow.java:125:4:125:8 | ...=... | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:125:4:125:8 | ...=... | TestThrow.java:128:3:128:13 | stmt | -| TestThrow.java:125:4:125:9 | stmt | TestThrow.java:125:8:125:8 | 3 | +| TestThrow.java:125:4:125:8 | ...=... | TestThrow.java:128:3:128:13 | if (...) | +| TestThrow.java:125:4:125:9 | ...; | TestThrow.java:125:8:125:8 | 3 | | TestThrow.java:125:8:125:8 | 3 | TestThrow.java:125:4:125:8 | ...=... | -| TestThrow.java:128:3:128:13 | stmt | TestThrow.java:128:7:128:7 | z | +| TestThrow.java:128:3:128:13 | if (...) | TestThrow.java:128:7:128:7 | z | | TestThrow.java:128:7:128:7 | z | TestThrow.java:128:12:128:12 | 1 | -| TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:129:3:131:3 | stmt | -| TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:133:3:133:9 | stmt | +| TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:129:3:131:3 | { ... } | +| TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:133:3:133:9 | ...; | | TestThrow.java:128:12:128:12 | 1 | TestThrow.java:128:7:128:12 | ... == ... | -| TestThrow.java:129:3:131:3 | stmt | TestThrow.java:130:10:130:24 | new Exception(...) | -| TestThrow.java:130:4:130:25 | stmt | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:130:10:130:24 | new Exception(...) | TestThrow.java:130:4:130:25 | stmt | +| TestThrow.java:129:3:131:3 | { ... } | TestThrow.java:130:10:130:24 | new Exception(...) | +| TestThrow.java:130:4:130:25 | throw ... | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:130:10:130:24 | new Exception(...) | TestThrow.java:130:4:130:25 | throw ... | | TestThrow.java:133:3:133:8 | ...=... | TestThrow.java:15:14:15:14 | f | -| TestThrow.java:133:3:133:9 | stmt | TestThrow.java:133:8:133:8 | 1 | +| TestThrow.java:133:3:133:9 | ...; | TestThrow.java:133:8:133:8 | 1 | | TestThrow.java:133:7:133:8 | -... | TestThrow.java:133:3:133:8 | ...=... | | TestThrow.java:133:8:133:8 | 1 | TestThrow.java:133:7:133:8 | -... | diff --git a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected index 6f8efd945d6..f1aebd2055f 100644 --- a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected @@ -1,15 +1,15 @@ +| TestThrow2.java:3:7:3:16 | ...; | TestThrow2.java:3:7:3:16 | (...) | | TestThrow2.java:3:7:3:16 | (...) | TestThrow2.java:3:7:3:16 | TestThrow2 | -| TestThrow2.java:3:7:3:16 | stmt | TestThrow2.java:3:7:3:16 | (...) | -| TestThrow2.java:3:7:3:16 | stmt | TestThrow2.java:3:7:3:16 | super(...) | -| TestThrow2.java:3:7:3:16 | stmt | TestThrow2.java:5:2:11:2 | stmt | -| TestThrow2.java:3:7:3:16 | super(...) | TestThrow2.java:3:7:3:16 | stmt | -| TestThrow2.java:5:2:11:2 | stmt | TestThrow2.java:6:3:10:3 | stmt | -| TestThrow2.java:6:3:10:3 | stmt | TestThrow2.java:6:7:8:3 | stmt | -| TestThrow2.java:6:7:8:3 | stmt | TestThrow2.java:7:4:7:13 | stmt | +| TestThrow2.java:3:7:3:16 | super(...) | TestThrow2.java:3:7:3:16 | ...; | +| TestThrow2.java:3:7:3:16 | { ... } | TestThrow2.java:3:7:3:16 | super(...) | +| TestThrow2.java:3:7:3:16 | { ... } | TestThrow2.java:5:2:11:2 | { ... } | +| TestThrow2.java:5:2:11:2 | { ... } | TestThrow2.java:6:3:10:3 | try ... | +| TestThrow2.java:6:3:10:3 | try ... | TestThrow2.java:6:7:8:3 | { ... } | +| TestThrow2.java:6:7:8:3 | { ... } | TestThrow2.java:7:4:7:13 | ...; | | TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:3:7:3:16 | | -| TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:8:5:8:23 | stmt | -| TestThrow2.java:7:4:7:13 | stmt | TestThrow2.java:7:4:7:12 | thrower(...) | -| TestThrow2.java:8:5:8:23 | stmt | TestThrow2.java:8:22:8:22 | e | -| TestThrow2.java:8:22:8:22 | e | TestThrow2.java:8:25:10:3 | stmt | -| TestThrow2.java:8:25:10:3 | stmt | TestThrow2.java:9:4:9:4 | stmt | -| TestThrow2.java:9:4:9:4 | stmt | TestThrow2.java:3:7:3:16 | | +| TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:8:5:8:23 | catch (...) | +| TestThrow2.java:7:4:7:13 | ...; | TestThrow2.java:7:4:7:12 | thrower(...) | +| TestThrow2.java:8:5:8:23 | catch (...) | TestThrow2.java:8:22:8:22 | e | +| TestThrow2.java:8:22:8:22 | e | TestThrow2.java:8:25:10:3 | { ... } | +| TestThrow2.java:8:25:10:3 | { ... } | TestThrow2.java:9:4:9:4 | ; | +| TestThrow2.java:9:4:9:4 | ; | TestThrow2.java:3:7:3:16 | | diff --git a/java/ql/test/library-tests/successors/TestTryCatch/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestTryCatch/FalseSuccessors.expected index 427a1014398..cfe3896fb66 100644 --- a/java/ql/test/library-tests/successors/TestTryCatch/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestTryCatch/FalseSuccessors.expected @@ -1 +1 @@ -| TestTryCatch.java:27:19:27:24 | ... < ... | TestTryCatch.java:42:3:42:12 | stmt | +| TestTryCatch.java:27:19:27:24 | ... < ... | TestTryCatch.java:42:3:42:12 | ...; | diff --git a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected index db1f8d15d83..205367d9bd9 100644 --- a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected @@ -1,121 +1,121 @@ -| TestTryCatch.java:3:14:3:25 | stmt | TestTryCatch.java:3:14:3:25 | super(...) | | TestTryCatch.java:3:14:3:25 | super(...) | TestTryCatch.java:3:14:3:25 | TestTryCatch | -| TestTryCatch.java:5:2:43:2 | stmt | TestTryCatch.java:6:3:23:3 | stmt | -| TestTryCatch.java:6:3:23:3 | stmt | TestTryCatch.java:7:3:12:3 | stmt | -| TestTryCatch.java:7:3:12:3 | stmt | TestTryCatch.java:8:4:8:29 | stmt | +| TestTryCatch.java:3:14:3:25 | { ... } | TestTryCatch.java:3:14:3:25 | super(...) | +| TestTryCatch.java:5:2:43:2 | { ... } | TestTryCatch.java:6:3:23:3 | try ... | +| TestTryCatch.java:6:3:23:3 | try ... | TestTryCatch.java:7:3:12:3 | { ... } | +| TestTryCatch.java:7:3:12:3 | { ... } | TestTryCatch.java:8:4:8:29 | ...; | | TestTryCatch.java:8:4:8:13 | System.out | TestTryCatch.java:8:23:8:27 | "Foo" | -| TestTryCatch.java:8:4:8:28 | println(...) | TestTryCatch.java:9:4:9:18 | stmt | -| TestTryCatch.java:8:4:8:28 | println(...) | TestTryCatch.java:12:5:12:23 | stmt | -| TestTryCatch.java:8:4:8:28 | println(...) | TestTryCatch.java:19:3:23:3 | stmt | -| TestTryCatch.java:8:4:8:29 | stmt | TestTryCatch.java:8:4:8:13 | System.out | +| TestTryCatch.java:8:4:8:28 | println(...) | TestTryCatch.java:9:4:9:18 | local variable declaration | +| TestTryCatch.java:8:4:8:28 | println(...) | TestTryCatch.java:12:5:12:23 | catch (...) | +| TestTryCatch.java:8:4:8:28 | println(...) | TestTryCatch.java:19:3:23:3 | { ... } | +| TestTryCatch.java:8:4:8:29 | ...; | TestTryCatch.java:8:4:8:13 | System.out | | TestTryCatch.java:8:23:8:27 | "Foo" | TestTryCatch.java:8:4:8:28 | println(...) | -| TestTryCatch.java:9:4:9:18 | stmt | TestTryCatch.java:9:12:9:13 | 12 | -| TestTryCatch.java:9:8:9:17 | y | TestTryCatch.java:10:4:10:29 | stmt | +| TestTryCatch.java:9:4:9:18 | local variable declaration | TestTryCatch.java:9:12:9:13 | 12 | +| TestTryCatch.java:9:8:9:17 | y | TestTryCatch.java:10:4:10:29 | ...; | | TestTryCatch.java:9:12:9:13 | 12 | TestTryCatch.java:9:17:9:17 | 3 | | TestTryCatch.java:9:12:9:17 | ... + ... | TestTryCatch.java:9:8:9:17 | y | | TestTryCatch.java:9:17:9:17 | 3 | TestTryCatch.java:9:12:9:17 | ... + ... | | TestTryCatch.java:10:4:10:13 | System.out | TestTryCatch.java:10:23:10:27 | "Bar" | -| TestTryCatch.java:10:4:10:28 | println(...) | TestTryCatch.java:11:4:11:13 | stmt | -| TestTryCatch.java:10:4:10:28 | println(...) | TestTryCatch.java:12:5:12:23 | stmt | -| TestTryCatch.java:10:4:10:28 | println(...) | TestTryCatch.java:19:3:23:3 | stmt | -| TestTryCatch.java:10:4:10:29 | stmt | TestTryCatch.java:10:4:10:13 | System.out | +| TestTryCatch.java:10:4:10:28 | println(...) | TestTryCatch.java:11:4:11:13 | ...; | +| TestTryCatch.java:10:4:10:28 | println(...) | TestTryCatch.java:12:5:12:23 | catch (...) | +| TestTryCatch.java:10:4:10:28 | println(...) | TestTryCatch.java:19:3:23:3 | { ... } | +| TestTryCatch.java:10:4:10:29 | ...; | TestTryCatch.java:10:4:10:13 | System.out | | TestTryCatch.java:10:23:10:27 | "Bar" | TestTryCatch.java:10:4:10:28 | println(...) | -| TestTryCatch.java:11:4:11:12 | ...=... | TestTryCatch.java:19:3:23:3 | stmt | -| TestTryCatch.java:11:4:11:13 | stmt | TestTryCatch.java:11:8:11:8 | y | +| TestTryCatch.java:11:4:11:12 | ...=... | TestTryCatch.java:19:3:23:3 | { ... } | +| TestTryCatch.java:11:4:11:13 | ...; | TestTryCatch.java:11:8:11:8 | y | | TestTryCatch.java:11:8:11:8 | y | TestTryCatch.java:11:12:11:12 | 1 | | TestTryCatch.java:11:8:11:12 | ... + ... | TestTryCatch.java:11:4:11:12 | ...=... | | TestTryCatch.java:11:12:11:12 | 1 | TestTryCatch.java:11:8:11:12 | ... + ... | -| TestTryCatch.java:12:5:12:23 | stmt | TestTryCatch.java:12:22:12:22 | e | -| TestTryCatch.java:12:22:12:22 | e | TestTryCatch.java:13:3:18:3 | stmt | -| TestTryCatch.java:13:3:18:3 | stmt | TestTryCatch.java:14:4:14:13 | stmt | -| TestTryCatch.java:14:4:14:13 | stmt | TestTryCatch.java:14:12:14:12 | 1 | -| TestTryCatch.java:14:8:14:12 | x | TestTryCatch.java:15:4:15:37 | stmt | +| TestTryCatch.java:12:5:12:23 | catch (...) | TestTryCatch.java:12:22:12:22 | e | +| TestTryCatch.java:12:22:12:22 | e | TestTryCatch.java:13:3:18:3 | { ... } | +| TestTryCatch.java:13:3:18:3 | { ... } | TestTryCatch.java:14:4:14:13 | local variable declaration | +| TestTryCatch.java:14:4:14:13 | local variable declaration | TestTryCatch.java:14:12:14:12 | 1 | +| TestTryCatch.java:14:8:14:12 | x | TestTryCatch.java:15:4:15:37 | ...; | | TestTryCatch.java:14:12:14:12 | 1 | TestTryCatch.java:14:8:14:12 | x | | TestTryCatch.java:15:4:15:13 | System.out | TestTryCatch.java:15:23:15:31 | "Error: " | -| TestTryCatch.java:15:4:15:36 | println(...) | TestTryCatch.java:16:4:16:13 | stmt | -| TestTryCatch.java:15:4:15:37 | stmt | TestTryCatch.java:15:4:15:13 | System.out | +| TestTryCatch.java:15:4:15:36 | println(...) | TestTryCatch.java:16:4:16:13 | ...; | +| TestTryCatch.java:15:4:15:37 | ...; | TestTryCatch.java:15:4:15:13 | System.out | | TestTryCatch.java:15:23:15:31 | "Error: " | TestTryCatch.java:15:35:15:35 | e | | TestTryCatch.java:15:23:15:35 | ... + ... | TestTryCatch.java:15:4:15:36 | println(...) | | TestTryCatch.java:15:35:15:35 | e | TestTryCatch.java:15:23:15:35 | ... + ... | -| TestTryCatch.java:16:4:16:12 | ...=... | TestTryCatch.java:17:4:17:10 | stmt | -| TestTryCatch.java:16:4:16:13 | stmt | TestTryCatch.java:16:8:16:8 | x | +| TestTryCatch.java:16:4:16:12 | ...=... | TestTryCatch.java:17:4:17:10 | return ... | +| TestTryCatch.java:16:4:16:13 | ...; | TestTryCatch.java:16:8:16:8 | x | | TestTryCatch.java:16:8:16:8 | x | TestTryCatch.java:16:12:16:12 | 1 | | TestTryCatch.java:16:8:16:12 | ... + ... | TestTryCatch.java:16:4:16:12 | ...=... | | TestTryCatch.java:16:12:16:12 | 1 | TestTryCatch.java:16:8:16:12 | ... + ... | -| TestTryCatch.java:17:4:17:10 | stmt | TestTryCatch.java:19:3:23:3 | stmt | -| TestTryCatch.java:19:3:23:3 | stmt | TestTryCatch.java:20:4:20:14 | stmt | -| TestTryCatch.java:20:4:20:14 | stmt | TestTryCatch.java:20:12:20:13 | 12 | -| TestTryCatch.java:20:8:20:13 | y | TestTryCatch.java:21:4:21:33 | stmt | +| TestTryCatch.java:17:4:17:10 | return ... | TestTryCatch.java:19:3:23:3 | { ... } | +| TestTryCatch.java:19:3:23:3 | { ... } | TestTryCatch.java:20:4:20:14 | local variable declaration | +| TestTryCatch.java:20:4:20:14 | local variable declaration | TestTryCatch.java:20:12:20:13 | 12 | +| TestTryCatch.java:20:8:20:13 | y | TestTryCatch.java:21:4:21:33 | ...; | | TestTryCatch.java:20:12:20:13 | 12 | TestTryCatch.java:20:8:20:13 | y | | TestTryCatch.java:21:4:21:13 | System.out | TestTryCatch.java:21:23:21:31 | "Finally" | -| TestTryCatch.java:21:4:21:32 | println(...) | TestTryCatch.java:22:4:22:13 | stmt | -| TestTryCatch.java:21:4:21:33 | stmt | TestTryCatch.java:21:4:21:13 | System.out | +| TestTryCatch.java:21:4:21:32 | println(...) | TestTryCatch.java:22:4:22:13 | ...; | +| TestTryCatch.java:21:4:21:33 | ...; | TestTryCatch.java:21:4:21:13 | System.out | | TestTryCatch.java:21:23:21:31 | "Finally" | TestTryCatch.java:21:4:21:32 | println(...) | | TestTryCatch.java:22:4:22:12 | ...=... | TestTryCatch.java:4:14:4:14 | f | -| TestTryCatch.java:22:4:22:12 | ...=... | TestTryCatch.java:24:3:24:13 | stmt | -| TestTryCatch.java:22:4:22:13 | stmt | TestTryCatch.java:22:8:22:8 | y | +| TestTryCatch.java:22:4:22:12 | ...=... | TestTryCatch.java:24:3:24:13 | local variable declaration | +| TestTryCatch.java:22:4:22:13 | ...; | TestTryCatch.java:22:8:22:8 | y | | TestTryCatch.java:22:8:22:8 | y | TestTryCatch.java:22:12:22:12 | 1 | | TestTryCatch.java:22:8:22:12 | ... + ... | TestTryCatch.java:22:4:22:12 | ...=... | | TestTryCatch.java:22:12:22:12 | 1 | TestTryCatch.java:22:8:22:12 | ... + ... | -| TestTryCatch.java:24:3:24:13 | stmt | TestTryCatch.java:24:11:24:12 | 12 | -| TestTryCatch.java:24:7:24:12 | z | TestTryCatch.java:25:3:25:12 | stmt | +| TestTryCatch.java:24:3:24:13 | local variable declaration | TestTryCatch.java:24:11:24:12 | 12 | +| TestTryCatch.java:24:7:24:12 | z | TestTryCatch.java:25:3:25:12 | ...; | | TestTryCatch.java:24:11:24:12 | 12 | TestTryCatch.java:24:7:24:12 | z | -| TestTryCatch.java:25:3:25:11 | ...=... | TestTryCatch.java:27:3:27:30 | stmt | -| TestTryCatch.java:25:3:25:12 | stmt | TestTryCatch.java:25:7:25:7 | z | +| TestTryCatch.java:25:3:25:11 | ...=... | TestTryCatch.java:27:3:27:30 | for (...) | +| TestTryCatch.java:25:3:25:12 | ...; | TestTryCatch.java:25:7:25:7 | z | | TestTryCatch.java:25:7:25:7 | z | TestTryCatch.java:25:11:25:11 | 1 | | TestTryCatch.java:25:7:25:11 | ... + ... | TestTryCatch.java:25:3:25:11 | ...=... | | TestTryCatch.java:25:11:25:11 | 1 | TestTryCatch.java:25:7:25:11 | ... + ... | -| TestTryCatch.java:27:3:27:30 | stmt | TestTryCatch.java:27:16:27:16 | 0 | +| TestTryCatch.java:27:3:27:30 | for (...) | TestTryCatch.java:27:16:27:16 | 0 | | TestTryCatch.java:27:12:27:16 | q | TestTryCatch.java:27:19:27:19 | q | | TestTryCatch.java:27:16:27:16 | 0 | TestTryCatch.java:27:12:27:16 | q | | TestTryCatch.java:27:19:27:19 | q | TestTryCatch.java:27:23:27:24 | 10 | -| TestTryCatch.java:27:19:27:24 | ... < ... | TestTryCatch.java:28:3:41:3 | stmt | -| TestTryCatch.java:27:19:27:24 | ... < ... | TestTryCatch.java:42:3:42:12 | stmt | +| TestTryCatch.java:27:19:27:24 | ... < ... | TestTryCatch.java:28:3:41:3 | { ... } | +| TestTryCatch.java:27:19:27:24 | ... < ... | TestTryCatch.java:42:3:42:12 | ...; | | TestTryCatch.java:27:23:27:24 | 10 | TestTryCatch.java:27:19:27:24 | ... < ... | | TestTryCatch.java:27:27:27:27 | q | TestTryCatch.java:27:27:27:29 | ...++ | | TestTryCatch.java:27:27:27:29 | ...++ | TestTryCatch.java:27:19:27:19 | q | -| TestTryCatch.java:28:3:41:3 | stmt | TestTryCatch.java:29:4:40:4 | stmt | -| TestTryCatch.java:29:4:40:4 | stmt | TestTryCatch.java:30:4:35:4 | stmt | -| TestTryCatch.java:30:4:35:4 | stmt | TestTryCatch.java:31:5:31:30 | stmt | +| TestTryCatch.java:28:3:41:3 | { ... } | TestTryCatch.java:29:4:40:4 | try ... | +| TestTryCatch.java:29:4:40:4 | try ... | TestTryCatch.java:30:4:35:4 | { ... } | +| TestTryCatch.java:30:4:35:4 | { ... } | TestTryCatch.java:31:5:31:30 | ...; | | TestTryCatch.java:31:5:31:14 | System.out | TestTryCatch.java:31:24:31:28 | "Foo" | -| TestTryCatch.java:31:5:31:29 | println(...) | TestTryCatch.java:32:5:32:19 | stmt | -| TestTryCatch.java:31:5:31:29 | println(...) | TestTryCatch.java:35:6:35:31 | stmt | -| TestTryCatch.java:31:5:31:30 | stmt | TestTryCatch.java:31:5:31:14 | System.out | +| TestTryCatch.java:31:5:31:29 | println(...) | TestTryCatch.java:32:5:32:19 | local variable declaration | +| TestTryCatch.java:31:5:31:29 | println(...) | TestTryCatch.java:35:6:35:31 | catch (...) | +| TestTryCatch.java:31:5:31:30 | ...; | TestTryCatch.java:31:5:31:14 | System.out | | TestTryCatch.java:31:24:31:28 | "Foo" | TestTryCatch.java:31:5:31:29 | println(...) | -| TestTryCatch.java:32:5:32:19 | stmt | TestTryCatch.java:32:13:32:14 | 12 | -| TestTryCatch.java:32:9:32:18 | y | TestTryCatch.java:33:5:33:30 | stmt | +| TestTryCatch.java:32:5:32:19 | local variable declaration | TestTryCatch.java:32:13:32:14 | 12 | +| TestTryCatch.java:32:9:32:18 | y | TestTryCatch.java:33:5:33:30 | ...; | | TestTryCatch.java:32:13:32:14 | 12 | TestTryCatch.java:32:18:32:18 | 3 | | TestTryCatch.java:32:13:32:18 | ... + ... | TestTryCatch.java:32:9:32:18 | y | | TestTryCatch.java:32:18:32:18 | 3 | TestTryCatch.java:32:13:32:18 | ... + ... | | TestTryCatch.java:33:5:33:14 | System.out | TestTryCatch.java:33:24:33:28 | "Bar" | -| TestTryCatch.java:33:5:33:29 | println(...) | TestTryCatch.java:34:5:34:14 | stmt | -| TestTryCatch.java:33:5:33:29 | println(...) | TestTryCatch.java:35:6:35:31 | stmt | -| TestTryCatch.java:33:5:33:30 | stmt | TestTryCatch.java:33:5:33:14 | System.out | +| TestTryCatch.java:33:5:33:29 | println(...) | TestTryCatch.java:34:5:34:14 | ...; | +| TestTryCatch.java:33:5:33:29 | println(...) | TestTryCatch.java:35:6:35:31 | catch (...) | +| TestTryCatch.java:33:5:33:30 | ...; | TestTryCatch.java:33:5:33:14 | System.out | | TestTryCatch.java:33:24:33:28 | "Bar" | TestTryCatch.java:33:5:33:29 | println(...) | | TestTryCatch.java:34:5:34:13 | ...=... | TestTryCatch.java:27:27:27:27 | q | -| TestTryCatch.java:34:5:34:14 | stmt | TestTryCatch.java:34:9:34:9 | y | +| TestTryCatch.java:34:5:34:14 | ...; | TestTryCatch.java:34:9:34:9 | y | | TestTryCatch.java:34:9:34:9 | y | TestTryCatch.java:34:13:34:13 | 1 | | TestTryCatch.java:34:9:34:13 | ... + ... | TestTryCatch.java:34:5:34:13 | ...=... | | TestTryCatch.java:34:13:34:13 | 1 | TestTryCatch.java:34:9:34:13 | ... + ... | -| TestTryCatch.java:35:6:35:31 | stmt | TestTryCatch.java:35:30:35:30 | e | -| TestTryCatch.java:35:30:35:30 | e | TestTryCatch.java:36:4:40:4 | stmt | -| TestTryCatch.java:36:4:40:4 | stmt | TestTryCatch.java:37:5:37:14 | stmt | -| TestTryCatch.java:37:5:37:14 | stmt | TestTryCatch.java:37:13:37:13 | 1 | -| TestTryCatch.java:37:9:37:13 | x | TestTryCatch.java:38:5:38:38 | stmt | +| TestTryCatch.java:35:6:35:31 | catch (...) | TestTryCatch.java:35:30:35:30 | e | +| TestTryCatch.java:35:30:35:30 | e | TestTryCatch.java:36:4:40:4 | { ... } | +| TestTryCatch.java:36:4:40:4 | { ... } | TestTryCatch.java:37:5:37:14 | local variable declaration | +| TestTryCatch.java:37:5:37:14 | local variable declaration | TestTryCatch.java:37:13:37:13 | 1 | +| TestTryCatch.java:37:9:37:13 | x | TestTryCatch.java:38:5:38:38 | ...; | | TestTryCatch.java:37:13:37:13 | 1 | TestTryCatch.java:37:9:37:13 | x | | TestTryCatch.java:38:5:38:14 | System.out | TestTryCatch.java:38:24:38:32 | "Error: " | -| TestTryCatch.java:38:5:38:37 | println(...) | TestTryCatch.java:39:5:39:14 | stmt | -| TestTryCatch.java:38:5:38:38 | stmt | TestTryCatch.java:38:5:38:14 | System.out | +| TestTryCatch.java:38:5:38:37 | println(...) | TestTryCatch.java:39:5:39:14 | ...; | +| TestTryCatch.java:38:5:38:38 | ...; | TestTryCatch.java:38:5:38:14 | System.out | | TestTryCatch.java:38:24:38:32 | "Error: " | TestTryCatch.java:38:36:38:36 | e | | TestTryCatch.java:38:24:38:36 | ... + ... | TestTryCatch.java:38:5:38:37 | println(...) | | TestTryCatch.java:38:36:38:36 | e | TestTryCatch.java:38:24:38:36 | ... + ... | | TestTryCatch.java:39:5:39:13 | ...=... | TestTryCatch.java:27:27:27:27 | q | -| TestTryCatch.java:39:5:39:14 | stmt | TestTryCatch.java:39:9:39:9 | x | +| TestTryCatch.java:39:5:39:14 | ...; | TestTryCatch.java:39:9:39:9 | x | | TestTryCatch.java:39:9:39:9 | x | TestTryCatch.java:39:13:39:13 | 1 | | TestTryCatch.java:39:9:39:13 | ... + ... | TestTryCatch.java:39:5:39:13 | ...=... | | TestTryCatch.java:39:13:39:13 | 1 | TestTryCatch.java:39:9:39:13 | ... + ... | | TestTryCatch.java:42:3:42:11 | ...=... | TestTryCatch.java:4:14:4:14 | f | -| TestTryCatch.java:42:3:42:12 | stmt | TestTryCatch.java:42:7:42:7 | z | +| TestTryCatch.java:42:3:42:12 | ...; | TestTryCatch.java:42:7:42:7 | z | | TestTryCatch.java:42:7:42:7 | z | TestTryCatch.java:42:11:42:11 | 2 | | TestTryCatch.java:42:7:42:11 | ... + ... | TestTryCatch.java:42:3:42:11 | ...=... | | TestTryCatch.java:42:11:42:11 | 2 | TestTryCatch.java:42:7:42:11 | ... + ... | diff --git a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected index 86c3f054f15..8084acd7aa4 100644 --- a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected @@ -1,37 +1,37 @@ -| TestTryWithResources.java:6:14:6:33 | stmt | TestTryWithResources.java:6:14:6:33 | super(...) | | TestTryWithResources.java:6:14:6:33 | super(...) | TestTryWithResources.java:6:14:6:33 | TestTryWithResources | -| TestTryWithResources.java:7:60:16:2 | stmt | TestTryWithResources.java:8:3:15:3 | stmt | -| TestTryWithResources.java:8:3:15:3 | stmt | TestTryWithResources.java:8:8:8:58 | stmt | -| TestTryWithResources.java:8:8:8:58 | stmt | TestTryWithResources.java:8:50:8:53 | args | -| TestTryWithResources.java:8:24:8:57 | fis | TestTryWithResources.java:9:4:9:55 | stmt | +| TestTryWithResources.java:6:14:6:33 | { ... } | TestTryWithResources.java:6:14:6:33 | super(...) | +| TestTryWithResources.java:7:60:16:2 | { ... } | TestTryWithResources.java:8:3:15:3 | try ... | +| TestTryWithResources.java:8:3:15:3 | try ... | TestTryWithResources.java:8:8:8:58 | local variable declaration | +| TestTryWithResources.java:8:8:8:58 | local variable declaration | TestTryWithResources.java:8:50:8:53 | args | +| TestTryWithResources.java:8:24:8:57 | fis | TestTryWithResources.java:9:4:9:55 | local variable declaration | | TestTryWithResources.java:8:30:8:57 | new FileInputStream(...) | TestTryWithResources.java:8:24:8:57 | fis | -| TestTryWithResources.java:8:30:8:57 | new FileInputStream(...) | TestTryWithResources.java:11:5:11:35 | stmt | -| TestTryWithResources.java:8:30:8:57 | new FileInputStream(...) | TestTryWithResources.java:13:13:15:3 | stmt | +| TestTryWithResources.java:8:30:8:57 | new FileInputStream(...) | TestTryWithResources.java:11:5:11:35 | catch (...) | +| TestTryWithResources.java:8:30:8:57 | new FileInputStream(...) | TestTryWithResources.java:13:13:15:3 | { ... } | | TestTryWithResources.java:8:50:8:53 | args | TestTryWithResources.java:8:55:8:55 | 0 | | TestTryWithResources.java:8:50:8:56 | ...[...] | TestTryWithResources.java:8:30:8:57 | new FileInputStream(...) | | TestTryWithResources.java:8:55:8:55 | 0 | TestTryWithResources.java:8:50:8:56 | ...[...] | -| TestTryWithResources.java:9:4:9:55 | stmt | TestTryWithResources.java:9:48:9:51 | args | -| TestTryWithResources.java:9:21:9:55 | fos | TestTryWithResources.java:9:58:11:3 | stmt | +| TestTryWithResources.java:9:4:9:55 | local variable declaration | TestTryWithResources.java:9:48:9:51 | args | +| TestTryWithResources.java:9:21:9:55 | fos | TestTryWithResources.java:9:58:11:3 | { ... } | | TestTryWithResources.java:9:27:9:55 | new FileOutputStream(...) | TestTryWithResources.java:9:21:9:55 | fos | -| TestTryWithResources.java:9:27:9:55 | new FileOutputStream(...) | TestTryWithResources.java:11:5:11:35 | stmt | -| TestTryWithResources.java:9:27:9:55 | new FileOutputStream(...) | TestTryWithResources.java:13:13:15:3 | stmt | +| TestTryWithResources.java:9:27:9:55 | new FileOutputStream(...) | TestTryWithResources.java:11:5:11:35 | catch (...) | +| TestTryWithResources.java:9:27:9:55 | new FileOutputStream(...) | TestTryWithResources.java:13:13:15:3 | { ... } | | TestTryWithResources.java:9:48:9:51 | args | TestTryWithResources.java:9:53:9:53 | 1 | | TestTryWithResources.java:9:48:9:54 | ...[...] | TestTryWithResources.java:9:27:9:55 | new FileOutputStream(...) | | TestTryWithResources.java:9:53:9:53 | 1 | TestTryWithResources.java:9:48:9:54 | ...[...] | -| TestTryWithResources.java:9:58:11:3 | stmt | TestTryWithResources.java:10:4:10:32 | stmt | +| TestTryWithResources.java:9:58:11:3 | { ... } | TestTryWithResources.java:10:4:10:32 | ...; | | TestTryWithResources.java:10:4:10:13 | System.out | TestTryWithResources.java:10:23:10:30 | "worked" | -| TestTryWithResources.java:10:4:10:31 | println(...) | TestTryWithResources.java:13:13:15:3 | stmt | -| TestTryWithResources.java:10:4:10:32 | stmt | TestTryWithResources.java:10:4:10:13 | System.out | +| TestTryWithResources.java:10:4:10:31 | println(...) | TestTryWithResources.java:13:13:15:3 | { ... } | +| TestTryWithResources.java:10:4:10:32 | ...; | TestTryWithResources.java:10:4:10:13 | System.out | | TestTryWithResources.java:10:23:10:30 | "worked" | TestTryWithResources.java:10:4:10:31 | println(...) | -| TestTryWithResources.java:11:5:11:35 | stmt | TestTryWithResources.java:11:34:11:34 | e | -| TestTryWithResources.java:11:34:11:34 | e | TestTryWithResources.java:11:37:13:3 | stmt | -| TestTryWithResources.java:11:37:13:3 | stmt | TestTryWithResources.java:12:4:12:40 | stmt | +| TestTryWithResources.java:11:5:11:35 | catch (...) | TestTryWithResources.java:11:34:11:34 | e | +| TestTryWithResources.java:11:34:11:34 | e | TestTryWithResources.java:11:37:13:3 | { ... } | +| TestTryWithResources.java:11:37:13:3 | { ... } | TestTryWithResources.java:12:4:12:40 | ...; | | TestTryWithResources.java:12:4:12:13 | System.out | TestTryWithResources.java:12:23:12:38 | "file not found" | -| TestTryWithResources.java:12:4:12:39 | println(...) | TestTryWithResources.java:13:13:15:3 | stmt | -| TestTryWithResources.java:12:4:12:40 | stmt | TestTryWithResources.java:12:4:12:13 | System.out | +| TestTryWithResources.java:12:4:12:39 | println(...) | TestTryWithResources.java:13:13:15:3 | { ... } | +| TestTryWithResources.java:12:4:12:40 | ...; | TestTryWithResources.java:12:4:12:13 | System.out | | TestTryWithResources.java:12:23:12:38 | "file not found" | TestTryWithResources.java:12:4:12:39 | println(...) | -| TestTryWithResources.java:13:13:15:3 | stmt | TestTryWithResources.java:14:4:14:33 | stmt | +| TestTryWithResources.java:13:13:15:3 | { ... } | TestTryWithResources.java:14:4:14:33 | ...; | | TestTryWithResources.java:14:4:14:13 | System.out | TestTryWithResources.java:14:23:14:31 | "finally" | | TestTryWithResources.java:14:4:14:32 | println(...) | TestTryWithResources.java:7:21:7:24 | main | -| TestTryWithResources.java:14:4:14:33 | stmt | TestTryWithResources.java:14:4:14:13 | System.out | +| TestTryWithResources.java:14:4:14:33 | ...; | TestTryWithResources.java:14:4:14:13 | System.out | | TestTryWithResources.java:14:23:14:31 | "finally" | TestTryWithResources.java:14:4:14:32 | println(...) | diff --git a/java/ql/test/library-tests/typeaccesses/PrintAst.expected b/java/ql/test/library-tests/typeaccesses/PrintAst.expected index 6df9a49f2b2..f9c2c3c4fb6 100644 --- a/java/ql/test/library-tests/typeaccesses/PrintAst.expected +++ b/java/ql/test/library-tests/typeaccesses/PrintAst.expected @@ -12,8 +12,8 @@ typeaccesses/Outer.java: # 0| [CompilationUnit] Outer # 3| 1: [Class] Outer # 4| 3: [Class] Inner -# 5| 4: [BlockStmt] stmt -# 6| 0: [LocalVariableDeclStmt] stmt +# 5| 4: [BlockStmt] { ... } +# 6| 0: [LocalVariableDeclStmt] local variable declaration # 6| 0: [TypeAccess] Object # 6| 1: [LocalVariableDeclExpr] o # 6| 0: [ArrayCreationExpr] new Outer[] @@ -38,8 +38,8 @@ typeaccesses/TA.java: # 7| 3: [Method] method1 # 7| 3: [TypeAccess] ArrayList # 7| 0: [TypeAccess] TA -# 7| 5: [BlockStmt] stmt -# 7| 0: [ReturnStmt] stmt +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ReturnStmt] return ... # 7| 0: [NullLiteral] null # 8| 4: [Method] method2 # 8| 3: [TypeAccess] void @@ -47,11 +47,11 @@ typeaccesses/TA.java: # 8| 0: [Parameter] param # 8| 0: [TypeAccess] ArrayList # 8| 0: [TypeAccess] TA -# 8| 5: [BlockStmt] stmt +# 8| 5: [BlockStmt] { ... } # 9| 5: [Method] method3 # 9| 3: [TypeAccess] void -# 9| 5: [BlockStmt] stmt -# 9| 0: [LocalVariableDeclStmt] stmt +# 9| 5: [BlockStmt] { ... } +# 9| 0: [LocalVariableDeclStmt] local variable declaration # 9| 0: [TypeAccess] ArrayList # 9| 0: [TypeAccess] TA # 9| 1: [LocalVariableDeclExpr] local @@ -61,11 +61,11 @@ typeaccesses/TA.java: # 10| 0: [TypeAccess] ArrayList # 10| 0: [TypeAccess] TA # 10| 3: [TypeAccess] void -# 10| 5: [BlockStmt] stmt +# 10| 5: [BlockStmt] { ... } # 11| 7: [Method] method5 # 11| 3: [TypeAccess] void -# 11| 5: [BlockStmt] stmt -# 11| 0: [ExprStmt] stmt +# 11| 5: [BlockStmt] { ... } +# 11| 0: [ExprStmt] ...; # 11| 0: [MethodAccess] toString(...) # 11| -1: [CastExpr] (...)... # 11| 0: [TypeAccess] ArrayList @@ -73,15 +73,15 @@ typeaccesses/TA.java: # 11| 1: [NullLiteral] null # 12| 8: [Method] method6 # 12| 3: [TypeAccess] void -# 12| 5: [BlockStmt] stmt -# 12| 0: [ExprStmt] stmt +# 12| 5: [BlockStmt] { ... } +# 12| 0: [ExprStmt] ...; # 12| 0: [ClassInstanceExpr] new ArrayList(...) # 12| -3: [TypeAccess] ArrayList # 12| 0: [TypeAccess] TA # 13| 9: [Method] method7 # 13| 3: [TypeAccess] void -# 13| 5: [BlockStmt] stmt -# 13| 0: [ExprStmt] stmt +# 13| 5: [BlockStmt] { ... } +# 13| 0: [ExprStmt] ...; # 13| 0: [MethodAccess] method3(...) # 13| -1: [TypeAccess] TA # 14| 10: [Class] Inner @@ -93,12 +93,12 @@ typeaccesses/TA.java: # 15| 3: [TypeAccess] TA.Inner # 15| -1: [TypeAccess] TA # 15| 0: [WildcardTypeAccess] ? ... -# 15| 5: [BlockStmt] stmt -# 15| 0: [ReturnStmt] stmt +# 15| 5: [BlockStmt] { ... } +# 15| 0: [ReturnStmt] return ... # 15| 0: [NullLiteral] null # 16| 12: [Method] method9 # 16| 3: [TypeAccess] List # 16| 0: [TypeAccess] TA -# 16| 5: [BlockStmt] stmt -# 16| 0: [ReturnStmt] stmt +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... # 16| 0: [NullLiteral] null diff --git a/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected b/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected index 2592d8fe1db..35178b0a349 100644 --- a/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected +++ b/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected @@ -1,9 +1,9 @@ -| unreachableblocks/Unreachable.java:6:14:8:3 | stmt | -| unreachableblocks/Unreachable.java:9:21:11:3 | stmt | -| unreachableblocks/Unreachable.java:12:22:14:3 | stmt | -| unreachableblocks/Unreachable.java:17:3:17:9 | stmt | -| unreachableblocks/Unreachable.java:19:3:19:9 | stmt | -| unreachableblocks/Unreachable.java:22:3:22:9 | stmt | -| unreachableblocks/Unreachable.java:24:3:24:9 | stmt | -| unreachableblocks/Unreachable.java:26:3:26:10 | stmt | -| unreachableblocks/Unreachable.java:27:3:27:10 | stmt | +| unreachableblocks/Unreachable.java:6:14:8:3 | { ... } | +| unreachableblocks/Unreachable.java:9:21:11:3 | { ... } | +| unreachableblocks/Unreachable.java:12:22:14:3 | { ... } | +| unreachableblocks/Unreachable.java:17:3:17:9 | case ... | +| unreachableblocks/Unreachable.java:19:3:19:9 | case ... | +| unreachableblocks/Unreachable.java:22:3:22:9 | case ... | +| unreachableblocks/Unreachable.java:24:3:24:9 | case ... | +| unreachableblocks/Unreachable.java:26:3:26:10 | case ... | +| unreachableblocks/Unreachable.java:27:3:27:10 | default | diff --git a/java/ql/test/library-tests/varargs/PrintAst.expected b/java/ql/test/library-tests/varargs/PrintAst.expected index 285ef6fc051..793c97b413c 100644 --- a/java/ql/test/library-tests/varargs/PrintAst.expected +++ b/java/ql/test/library-tests/varargs/PrintAst.expected @@ -7,14 +7,14 @@ varargs/Test.java: # 4| 0: [Parameter] is # 4| 0: [ArrayTypeAccess] ...[] # 4| 0: [TypeAccess] int -# 4| 5: [BlockStmt] stmt +# 4| 5: [BlockStmt] { ... } # 5| 4: [Method] g # 5| 3: [TypeAccess] void #-----| 4: (Parameters) # 5| 0: [Parameter] os # 5| 0: [ArrayTypeAccess] ...[] # 5| 0: [TypeAccess] Object -# 5| 5: [BlockStmt] stmt +# 5| 5: [BlockStmt] { ... } # 6| 5: [Method] h # 6| 3: [TypeAccess] void #-----| 4: (Parameters) @@ -23,21 +23,21 @@ varargs/Test.java: # 6| 1: [Parameter] ss # 6| 0: [ArrayTypeAccess] ...[] # 6| 0: [TypeAccess] String -# 6| 5: [BlockStmt] stmt +# 6| 5: [BlockStmt] { ... } # 8| 6: [Method] ff # 8| 3: [TypeAccess] void #-----| 4: (Parameters) # 8| 0: [Parameter] is # 8| 0: [ArrayTypeAccess] ...[] # 8| 0: [TypeAccess] int -# 8| 5: [BlockStmt] stmt +# 8| 5: [BlockStmt] { ... } # 9| 7: [Method] gg # 9| 3: [TypeAccess] void #-----| 4: (Parameters) # 9| 0: [Parameter] os # 9| 0: [ArrayTypeAccess] ...[] # 9| 0: [TypeAccess] Object -# 9| 5: [BlockStmt] stmt +# 9| 5: [BlockStmt] { ... } # 10| 8: [Method] hh # 10| 3: [TypeAccess] void #-----| 4: (Parameters) @@ -46,9 +46,9 @@ varargs/Test.java: # 10| 1: [Parameter] ss # 10| 0: [ArrayTypeAccess] ...[] # 10| 0: [TypeAccess] String -# 10| 5: [BlockStmt] stmt -# 11| 9: [BlockStmt] stmt -# 12| 0: [ExprStmt] stmt +# 10| 5: [BlockStmt] { ... } +# 11| 9: [BlockStmt] { ... } +# 12| 0: [ExprStmt] ...; # 12| 0: [MethodAccess] asList(...) # 12| -1: [TypeAccess] Arrays # 12| 0: [IntegerLiteral] 1 diff --git a/java/ql/test/query-tests/BusyWait/BusyWait.expected b/java/ql/test/query-tests/BusyWait/BusyWait.expected index 981e383d61d..3a6139cba7a 100644 --- a/java/ql/test/query-tests/BusyWait/BusyWait.expected +++ b/java/ql/test/query-tests/BusyWait/BusyWait.expected @@ -1,2 +1,2 @@ -| BusyWaits.java:4:4:4:19 | stmt | Prefer wait/notify or java.util.concurrent to communicate between threads. | -| BusyWaits.java:10:5:10:39 | stmt | Prefer wait/notify or java.util.concurrent to communicate between threads. | +| BusyWaits.java:4:4:4:19 | ...; | Prefer wait/notify or java.util.concurrent to communicate between threads. | +| BusyWaits.java:10:5:10:39 | ...; | Prefer wait/notify or java.util.concurrent to communicate between threads. | diff --git a/java/ql/test/query-tests/ConstantLoopCondition/ConstantLoopCondition.expected b/java/ql/test/query-tests/ConstantLoopCondition/ConstantLoopCondition.expected index 688cdd7f258..48fac80c81f 100644 --- a/java/ql/test/query-tests/ConstantLoopCondition/ConstantLoopCondition.expected +++ b/java/ql/test/query-tests/ConstantLoopCondition/ConstantLoopCondition.expected @@ -1,4 +1,4 @@ -| A.java:8:11:8:15 | !... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:8:5:8:16 | stmt | Loop | -| A.java:15:11:15:15 | ... > ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:14:5:14:19 | stmt | Loop | -| A.java:29:20:29:32 | ... < ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:29:5:29:38 | stmt | Loop | -| A.java:36:12:36:15 | cond | $@ might not terminate, as this loop condition is constant within the loop. | A.java:36:5:36:16 | stmt | Loop | +| A.java:8:11:8:15 | !... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:8:5:8:16 | while (...) | Loop | +| A.java:15:11:15:15 | ... > ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:14:5:14:19 | for (...) | Loop | +| A.java:29:20:29:32 | ... < ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:29:5:29:38 | for (...) | Loop | +| A.java:36:12:36:15 | cond | $@ might not terminate, as this loop condition is constant within the loop. | A.java:36:5:36:16 | while (...) | Loop | diff --git a/java/ql/test/query-tests/ContinueInFalseLoop/ContinueInFalseLoop.expected b/java/ql/test/query-tests/ContinueInFalseLoop/ContinueInFalseLoop.expected index 2ce5be1ec66..969f23f3976 100644 --- a/java/ql/test/query-tests/ContinueInFalseLoop/ContinueInFalseLoop.expected +++ b/java/ql/test/query-tests/ContinueInFalseLoop/ContinueInFalseLoop.expected @@ -1,3 +1,3 @@ -| A.java:14:9:14:17 | stmt | This 'continue' never re-runs the loop - the $@ is always false. | A.java:17:14:17:18 | false | loop condition | -| A.java:54:11:54:19 | stmt | This 'continue' never re-runs the loop - the $@ is always false. | A.java:57:16:57:20 | false | loop condition | -| A.java:79:9:79:17 | stmt | This 'continue' never re-runs the loop - the $@ is always false. | A.java:82:14:82:18 | false | loop condition | +| A.java:14:9:14:17 | continue | This 'continue' never re-runs the loop - the $@ is always false. | A.java:17:14:17:18 | false | loop condition | +| A.java:54:11:54:19 | continue | This 'continue' never re-runs the loop - the $@ is always false. | A.java:57:16:57:20 | false | loop condition | +| A.java:79:9:79:17 | continue | This 'continue' never re-runs the loop - the $@ is always false. | A.java:82:14:82:18 | false | loop condition | diff --git a/java/ql/test/query-tests/Declarations/BreakInSwitchCase.expected b/java/ql/test/query-tests/Declarations/BreakInSwitchCase.expected index 2800ea8afbb..a1f3e131c55 100644 --- a/java/ql/test/query-tests/Declarations/BreakInSwitchCase.expected +++ b/java/ql/test/query-tests/Declarations/BreakInSwitchCase.expected @@ -1,2 +1,2 @@ -| Test.java:14:4:14:10 | stmt | Switch case may fall through to the next case. Use a break or return to terminate this case. | -| Test.java:20:4:20:10 | stmt | Switch case may fall through to the next case. Use a break or return to terminate this case. | +| Test.java:14:4:14:10 | case ... | Switch case may fall through to the next case. Use a break or return to terminate this case. | +| Test.java:20:4:20:10 | case ... | Switch case may fall through to the next case. Use a break or return to terminate this case. | diff --git a/java/ql/test/query-tests/DoubleCheckedLocking/DoubleCheckedLocking.expected b/java/ql/test/query-tests/DoubleCheckedLocking/DoubleCheckedLocking.expected index 4882d80f3d4..a0be819c198 100644 --- a/java/ql/test/query-tests/DoubleCheckedLocking/DoubleCheckedLocking.expected +++ b/java/ql/test/query-tests/DoubleCheckedLocking/DoubleCheckedLocking.expected @@ -1,3 +1,3 @@ -| A.java:12:7:16:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:9:18:9:19 | s1 | s1 | -| A.java:40:7:45:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:36:13:36:14 | b1 | b1 | -| A.java:101:7:106:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:98:26:98:27 | b5 | b5 | +| A.java:12:7:16:7 | synchronized (...) | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:9:18:9:19 | s1 | s1 | +| A.java:40:7:45:7 | synchronized (...) | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:36:13:36:14 | b1 | b1 | +| A.java:101:7:106:7 | synchronized (...) | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:98:26:98:27 | b5 | b5 | diff --git a/java/ql/test/query-tests/Finally/FinallyMayNotComplete.expected b/java/ql/test/query-tests/Finally/FinallyMayNotComplete.expected index 07956a735b2..dff7495a2db 100644 --- a/java/ql/test/query-tests/Finally/FinallyMayNotComplete.expected +++ b/java/ql/test/query-tests/Finally/FinallyMayNotComplete.expected @@ -1,7 +1,7 @@ -| Finally.java:6:4:6:10 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | -| Finally.java:17:5:17:13 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | -| Finally.java:30:5:30:40 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | -| Finally.java:63:6:63:11 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | -| Finally.java:77:7:77:12 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | -| Finally.java:111:6:111:14 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | -| Finally.java:125:7:125:15 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:6:4:6:10 | return ... | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:17:5:17:13 | return ... | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:30:5:30:40 | throw ... | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:63:6:63:11 | break | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:77:7:77:12 | break | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:111:6:111:14 | continue | Leaving a finally-block with this statement can cause exceptions to silently disappear. | +| Finally.java:125:7:125:15 | continue | Leaving a finally-block with this statement can cause exceptions to silently disappear. | diff --git a/java/ql/test/query-tests/MissedTernaryOpportunity/MissedTernaryOpportunity.expected b/java/ql/test/query-tests/MissedTernaryOpportunity/MissedTernaryOpportunity.expected index afdc5bbf405..5490aecb085 100644 --- a/java/ql/test/query-tests/MissedTernaryOpportunity/MissedTernaryOpportunity.expected +++ b/java/ql/test/query-tests/MissedTernaryOpportunity/MissedTernaryOpportunity.expected @@ -1,6 +1,6 @@ -| MissedTernaryOpportunityTest.java:6:3:6:13 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. | -| MissedTernaryOpportunityTest.java:32:3:32:13 | stmt | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. | -| MissedTernaryOpportunityTest.java:74:9:74:19 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. | -| MissedTernaryOpportunityTest.java:133:9:133:18 | stmt | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. | -| MissedTernaryOpportunityTest.java:145:13:145:23 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. | -| MissedTernaryOpportunityTest.java:155:13:155:23 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. | +| MissedTernaryOpportunityTest.java:6:3:6:13 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. | +| MissedTernaryOpportunityTest.java:32:3:32:13 | if (...) | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. | +| MissedTernaryOpportunityTest.java:74:9:74:19 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. | +| MissedTernaryOpportunityTest.java:133:9:133:18 | if (...) | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. | +| MissedTernaryOpportunityTest.java:145:13:145:23 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. | +| MissedTernaryOpportunityTest.java:155:13:155:23 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. | diff --git a/java/ql/test/query-tests/PartiallyMaskedCatch/PartiallyMaskedCatch.expected b/java/ql/test/query-tests/PartiallyMaskedCatch/PartiallyMaskedCatch.expected index 91bef93e6d9..fb533a6802b 100644 --- a/java/ql/test/query-tests/PartiallyMaskedCatch/PartiallyMaskedCatch.expected +++ b/java/ql/test/query-tests/PartiallyMaskedCatch/PartiallyMaskedCatch.expected @@ -1,6 +1,6 @@ -| PartiallyMaskedCatchTest.java:16:5:16:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:12:5:12:24 | stmt | here for exceptions of type 'ExceptionB' | -| PartiallyMaskedCatchTest.java:16:5:16:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:14:5:14:24 | stmt | here for exceptions of type 'ExceptionA' | -| PartiallyMaskedCatchTest.java:26:5:26:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:22:5:22:47 | stmt | here for exceptions of type 'ExceptionB' | -| PartiallyMaskedCatchTest.java:26:5:26:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:24:5:24:43 | stmt | here for exceptions of type 'ExceptionA' | -| PartiallyMaskedCatchTest.java:36:5:36:44 | stmt | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:32:5:32:47 | stmt | here for exceptions of type 'ExceptionB' | -| PartiallyMaskedCatchTest.java:36:5:36:44 | stmt | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:34:5:34:51 | stmt | here for exceptions of type 'ExceptionA' | +| PartiallyMaskedCatchTest.java:16:5:16:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:12:5:12:24 | catch (...) | here for exceptions of type 'ExceptionB' | +| PartiallyMaskedCatchTest.java:16:5:16:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:14:5:14:24 | catch (...) | here for exceptions of type 'ExceptionA' | +| PartiallyMaskedCatchTest.java:26:5:26:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:22:5:22:47 | catch (...) | here for exceptions of type 'ExceptionB' | +| PartiallyMaskedCatchTest.java:26:5:26:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:24:5:24:43 | catch (...) | here for exceptions of type 'ExceptionA' | +| PartiallyMaskedCatchTest.java:36:5:36:44 | catch (...) | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:32:5:32:47 | catch (...) | here for exceptions of type 'ExceptionB' | +| PartiallyMaskedCatchTest.java:36:5:36:44 | catch (...) | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:34:5:34:51 | catch (...) | here for exceptions of type 'ExceptionA' | diff --git a/java/ql/test/query-tests/UseBraces/UseBraces.expected b/java/ql/test/query-tests/UseBraces/UseBraces.expected index e81eb013fbe..1ef1a0380df 100644 --- a/java/ql/test/query-tests/UseBraces/UseBraces.expected +++ b/java/ql/test/query-tests/UseBraces/UseBraces.expected @@ -1,14 +1,14 @@ -| UseBraces.java:28:4:28:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:29:4:29:7 | stmt | the next statement | UseBraces.java:27:3:27:10 | stmt | the control structure | -| UseBraces.java:32:4:32:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:32:9:32:12 | stmt | the next statement | UseBraces.java:31:3:31:10 | stmt | the control structure | -| UseBraces.java:58:4:58:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:59:4:59:7 | stmt | the next statement | UseBraces.java:53:3:53:10 | stmt | the control structure | -| UseBraces.java:66:4:66:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:66:10:66:13 | stmt | the next statement | UseBraces.java:61:3:61:10 | stmt | the control structure | -| UseBraces.java:82:4:82:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:83:4:83:7 | stmt | the next statement | UseBraces.java:81:3:81:14 | stmt | the control structure | -| UseBraces.java:87:4:87:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:87:9:87:12 | stmt | the next statement | UseBraces.java:86:3:86:14 | stmt | the control structure | -| UseBraces.java:112:4:112:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:113:4:113:7 | stmt | the next statement | UseBraces.java:111:3:111:25 | stmt | the control structure | -| UseBraces.java:116:4:116:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:116:9:116:12 | stmt | the next statement | UseBraces.java:115:3:115:25 | stmt | the control structure | -| UseBraces.java:132:4:132:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:133:4:133:7 | stmt | the next statement | UseBraces.java:131:3:131:24 | stmt | the control structure | -| UseBraces.java:136:4:136:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:136:9:136:12 | stmt | the next statement | UseBraces.java:135:3:135:24 | stmt | the control structure | -| UseBraces.java:145:4:145:12 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:147:4:147:7 | stmt | the next statement | UseBraces.java:144:3:144:12 | stmt | the control structure | -| UseBraces.java:166:4:166:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:167:4:167:7 | stmt | the next statement | UseBraces.java:165:8:165:17 | stmt | the control structure | -| UseBraces.java:176:4:176:15 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:178:4:178:7 | stmt | the next statement | UseBraces.java:175:3:175:11 | stmt | the control structure | -| UseBraces.java:186:4:186:12 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:188:4:188:7 | stmt | the next statement | UseBraces.java:185:3:185:14 | stmt | the control structure | +| UseBraces.java:28:4:28:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:29:4:29:7 | ...; | the next statement | UseBraces.java:27:3:27:10 | if (...) | the control structure | +| UseBraces.java:32:4:32:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:32:9:32:12 | ...; | the next statement | UseBraces.java:31:3:31:10 | if (...) | the control structure | +| UseBraces.java:58:4:58:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:59:4:59:7 | ...; | the next statement | UseBraces.java:53:3:53:10 | if (...) | the control structure | +| UseBraces.java:66:4:66:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:66:10:66:13 | ...; | the next statement | UseBraces.java:61:3:61:10 | if (...) | the control structure | +| UseBraces.java:82:4:82:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:83:4:83:7 | ...; | the next statement | UseBraces.java:81:3:81:14 | while (...) | the control structure | +| UseBraces.java:87:4:87:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:87:9:87:12 | ...; | the next statement | UseBraces.java:86:3:86:14 | while (...) | the control structure | +| UseBraces.java:112:4:112:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:113:4:113:7 | ...; | the next statement | UseBraces.java:111:3:111:25 | for (...) | the control structure | +| UseBraces.java:116:4:116:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:116:9:116:12 | ...; | the next statement | UseBraces.java:115:3:115:25 | for (...) | the control structure | +| UseBraces.java:132:4:132:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:133:4:133:7 | ...; | the next statement | UseBraces.java:131:3:131:24 | for (... : ...) | the control structure | +| UseBraces.java:136:4:136:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:136:9:136:12 | ...; | the next statement | UseBraces.java:135:3:135:24 | for (... : ...) | the control structure | +| UseBraces.java:145:4:145:12 | if (...) | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:147:4:147:7 | ...; | the next statement | UseBraces.java:144:3:144:12 | if (...) | the control structure | +| UseBraces.java:166:4:166:7 | ...; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:167:4:167:7 | ...; | the next statement | UseBraces.java:165:8:165:17 | if (...) | the control structure | +| UseBraces.java:176:4:176:15 | while (...) | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:178:4:178:7 | ...; | the next statement | UseBraces.java:175:3:175:11 | if (...) | the control structure | +| UseBraces.java:186:4:186:12 | if (...) | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:188:4:188:7 | ...; | the next statement | UseBraces.java:185:3:185:14 | while (...) | the control structure | diff --git a/java/ql/test/query-tests/lgtm-example-queries/returnstatement.expected b/java/ql/test/query-tests/lgtm-example-queries/returnstatement.expected index df91fd42f0a..c776293c8b8 100644 --- a/java/ql/test/query-tests/lgtm-example-queries/returnstatement.expected +++ b/java/ql/test/query-tests/lgtm-example-queries/returnstatement.expected @@ -1 +1 @@ -| Test.java:15:3:15:14 | stmt | +| Test.java:15:3:15:14 | return ... | diff --git a/java/ql/test/query-tests/security/CWE-835/semmle/tests/InfiniteLoop.expected b/java/ql/test/query-tests/security/CWE-835/semmle/tests/InfiniteLoop.expected index 9231ab29aa6..cb902de9249 100644 --- a/java/ql/test/query-tests/security/CWE-835/semmle/tests/InfiniteLoop.expected +++ b/java/ql/test/query-tests/security/CWE-835/semmle/tests/InfiniteLoop.expected @@ -1 +1 @@ -| InfiniteLoop.java:4:13:4:36 | stmt | Loop might not terminate, as termination depends in part on $@ being false but it is always true. | InfiniteLoop.java:4:27:4:30 | ... < ... | this test | +| InfiniteLoop.java:4:13:4:36 | for (...) | Loop might not terminate, as termination depends in part on $@ being false but it is always true. | InfiniteLoop.java:4:27:4:30 | ... < ... | this test | From e0a45507f835fa44b61b743c60d88df769d00488 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Mon, 31 May 2021 01:24:24 +0200 Subject: [PATCH 142/272] Java: Adjust toString() for statements --- java/ql/src/semmle/code/java/Statement.qll | 16 +- .../library-tests/arrays/PrintAst.expected | 6 +- .../library-tests/constants/PrintAst.expected | 162 +-- .../controlflow/basic/bbStmts.expected | 116 +- .../basic/bbStrictDominance.expected | 160 +-- .../controlflow/basic/bbSuccessor.expected | 30 +- .../basic/strictDominance.expected | 1066 ++++++++--------- .../basic/strictPostDominance.expected | 416 +++---- .../controlflow/dominance/dominator.expected | 128 +- .../test/library-tests/guards/guards.expected | 18 +- .../library-tests/guards/guardslogic.expected | 14 +- .../library-tests/guards12/PrintAst.expected | 2 +- .../MultiCatch/MultiCatchControlFlow.expected | 4 +- .../LocalVarDeclStmtChildren.expected | 22 +- .../localvars/TypeAccesses.expected | 12 +- .../library-tests/printAst/PrintAst.expected | 14 +- .../reflection/PrintAst.expected | 2 +- .../ql/test/library-tests/ssa/ssaDef.expected | 10 +- .../ql/test/library-tests/ssa/ssaPhi.expected | 20 +- .../ql/test/library-tests/ssa/ssaUse.expected | 10 +- .../library-tests/stmts/JumpTargets.expected | 10 +- .../CloseReaderTest/TestSucc.expected | 12 +- .../LoopVarReadTest/FalseSuccessors.expected | 2 +- .../LoopVarReadTest/TestSucc.expected | 20 +- .../SaveFileTest/FalseSuccessors.expected | 4 +- .../successors/SaveFileTest/TestSucc.expected | 50 +- .../SchackTest/FalseSuccessors.expected | 2 +- .../successors/SchackTest/TestSucc.expected | 22 +- .../TestBreak/FalseSuccessors.expected | 4 +- .../successors/TestBreak/TestSucc.expected | 86 +- .../TestContinue/FalseSuccessors.expected | 10 +- .../successors/TestContinue/TestSucc.expected | 38 +- .../TestDeclarations/TestSucc.expected | 36 +- .../TestFinally/FalseSuccessors.expected | 18 +- .../successors/TestFinally/TestSucc.expected | 152 +-- .../TestSucc.expected | 42 +- .../TestLoopBranch/FalseSuccessors.expected | 2 +- .../TestLoopBranch/TestSucc.expected | 176 +-- .../TestThrow/FalseSuccessors.expected | 2 +- .../successors/TestThrow/TestSucc.expected | 82 +- .../successors/TestThrow2/TestSucc.expected | 8 +- .../TestTryCatch/FalseSuccessors.expected | 2 +- .../successors/TestTryCatch/TestSucc.expected | 84 +- .../TestTryWithResources/TestSucc.expected | 20 +- .../typeaccesses/PrintAst.expected | 4 +- .../query-tests/BusyWait/BusyWait.expected | 4 +- .../ConstantLoopCondition.expected | 4 +- .../query-tests/UseBraces/UseBraces.expected | 28 +- .../semmle/tests/InfiniteLoop.expected | 2 +- 49 files changed, 1577 insertions(+), 1577 deletions(-) diff --git a/java/ql/src/semmle/code/java/Statement.qll b/java/ql/src/semmle/code/java/Statement.qll index 12e894cf073..ddae251a443 100755 --- a/java/ql/src/semmle/code/java/Statement.qll +++ b/java/ql/src/semmle/code/java/Statement.qll @@ -203,7 +203,7 @@ class ForStmt extends ConditionalStmt, @forstmt { override string pp() { result = "for (...;...;...) " + this.getStmt().pp() } - override string toString() { result = "for (...)" } + override string toString() { result = "for (...;...;...)" } override string getHalsteadID() { result = "ForStmt" } @@ -706,9 +706,9 @@ class ExprStmt extends Stmt, @exprstmt { /** Gets the expression of this expression statement. */ Expr getExpr() { result.getParent() = this } - override string pp() { result = "...;" } + override string pp() { result = ";" } - override string toString() { result = "...;" } + override string toString() { result = ";" } override string getHalsteadID() { result = "ExprStmt" } @@ -739,7 +739,7 @@ class LabeledStmt extends Stmt, @labeledstmt { override string getHalsteadID() { result = this.getLabel() + ":" } - override string toString() { result = "labeled statement" } + override string toString() { result = "